xiaodai
February 21, 2018, 8:47pm
1
Why isn’t this true: [mean, mean, mean] isa Vector{Function}
? but this is: [mean, mean, sum] isa Vector{Function}
?
Basically I am writing a function like this, but it’s not dispatching on applyfns2tuples([mean, mean,mean],[rand(5), rand(5), rand(5)])
.
function applyfns2tuples(fns::Vector{Functions}, tuples)
((fns1(tuples1) for (fns1,tuples1) in zip(fns, tuples)...)
end
Type covariance. Vector{Float64}
is not a Vector{Number}
. mean
is a function and every function is a type, so Vector{#mean}
where #mean <: Function
. Same thing as the number case.
If you want, you can do Function[mean, mean, mean]
to get Vector{Function}
.
For another option, see this package which really, really, really should be in Base
.
DNF
February 21, 2018, 9:02pm
4
This is the same phenomenon as
julia> Vector{Int} <: Vector{Number}
false
even though
julia> Int <: Number
true
I believe it has to do with type covariance.
On the other hand
julia> Vector{Int} <: Vector{T} where {T<:Number}
true
You can instead use
julia> [mean, mean, mean] isa Vector{T} where {T<:Function}
true
Or use shorthand notation
julia> [mean, mean, mean] isa Vector{<:Function}
true
2 Likes
xiaodai
February 21, 2018, 9:11pm
5
It makes sense now. That’s why Julia can specialise on functions where functions are passed as arguments
4 Likes
piever
February 21, 2018, 9:24pm
6
If you need to dispatch you can use Vector{<:Function}
which encompasses all the vectors of something that is a subtype of Function
DNF
February 21, 2018, 9:40pm
7
This will work, and simplifies your notation a bit (drop the splatting):
apply(funs::Vector{<:Function}, args) = (f(arg) for (f, arg) in zip(funs, args))
I played around and tried to use tuples instead of Vector{<:Function}
, but could not find a way to express it. For example,
julia> [mean, mean, sum] isa Vector{<:Function}
true
while
julia> (mean, mean, sum) isa NTuple{3, <:Function}
false
1 Like
julia> (mean, mean, sum) isa NTuple{3, Function}
true
julia> NTuple{3, <:Function}
Tuple{#s1,#s1,#s1} where #s1<:Function
2 Likes