Array of structs with generic function members?

82 Views Asked by At

I'm trying construct an array of structs where each instance contains a different function. I want to add these to an array in a loop.

Here's an example:

struct mystruc{F}
    σ::F
end

a = [mystruc(relu)]
for i in 1:3
 append!(a, [mystruc(identity), ])
end

As a side note, I have the option to preallocate the array I just couldn't figure out how to do with this type of struct.

1

There are 1 best solutions below

0
On BEST ANSWER

Each function has a type, which is exclusive to that function:

julia> typeof(x -> x) == typeof(x -> x)
false

Here we created the function x -> x twice, they are two different functions, so their types are not the same.

In your construction of a, you create an Array of that specific type:

julia> a = [mystruc(relu)]
1-element Array{mystruc{typeof(relu)},1}:
 mystruc{typeof(relu)}(relu)

julia> typeof(a)
Array{mystruc{typeof(relu)},1}

So when you push another function, we get an error, because this array can only contain objects of the type mystruc{typeof(relu)}.

julia> push!(a, mystruc(x -> 2x))
ERROR: MethodError: Cannot `convert` an object of type
  mystruc{var"#3#4"} to an object of type
  mystruc{typeof(relu)}
Closest candidates are:
  convert(::Type{T}, ::T) where T at essentials.jl:171
  mystruc{typeof(relu)}(::Any) where F at REPL[2]:2

Solution

When you construct a, tell Julia that the array will contain mystruc with any function:

julia> a = mystruc{<:Function}[mystruc(relu)]

and now it works!

julia> push!(a, mystruc(x -> 2x))
2-element Array{mystruc{#s1} where #s1<:Function,1}:
 mystruc{typeof(relu)}(relu)
 mystruc{var"#5#6"}(var"#5#6"())