Hi,
I saw fmap
as an extension of map
to functors and I want to use it convert type of element of arrays that are leaves of some struct:
Taking the doc example:
julia> using Functors
julia> struct Foo
x
y
end
julia> @functor Foo
julia> model = Foo(1, [1, 2, 3])
Foo(1, [1, 2, 3])
julia> fmap(float, model)
Foo(1.0, [1.0, 2.0, 3.0])
julia> fmap(Float32,model)
ERROR: MethodError: no method matching Float32(::Vector{Int64})
Closest candidates are:
(::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number}
@ Base char.jl:50
(::Type{T})(::Base.TwicePrecision) where T<:Number
@ Base twiceprecision.jl:266
(::Type{T})(::Complex) where T<:Real
@ Base complex.jl:44
...
Stacktrace:
[1] (::Functors.ExcludeWalk{Functors.DefaultWalk, DataType, typeof(Functors.isleaf)})(::Function, ::Vector{Int64})
@ Functors ~/.julia/packages/Functors/rlD70/src/walks.jl:106
[2] (::Functors.CachedWalk{Functors.ExcludeWalk{Functors.DefaultWalk, DataType, typeof(Functors.isleaf)}, Functors.NoKeyword})(::Function, ::Vector{Int64})
@ Functors ~/.julia/packages/Functors/rlD70/src/walks.jl:146
[3] (::Functors.var"#recurse#19"{Functors.CachedWalk{Functors.ExcludeWalk{Functors.DefaultWalk, DataType, typeof(Functors.isleaf)}, Functors.NoKeyword}})(xs::Vector{Int64})
@ Functors ~/.julia/packages/Functors/rlD70/src/walks.jl:37
[4] map
@ ./tuple.jl:274 [inlined]
[5] map(::Function, ::NamedTuple{(:x, :y), Tuple{Int64, Vector{Int64}}})
@ Base ./namedtuple.jl:219
[6] _map(f::Function, x::NamedTuple{(:x, :y), Tuple{Int64, Vector{Int64}}})
@ Functors ~/.julia/packages/Functors/rlD70/src/walks.jl:1
[7] (::Functors.DefaultWalk)(::Function, ::Foo)
@ Functors ~/.julia/packages/Functors/rlD70/src/walks.jl:76
[8] ExcludeWalk
@ ~/.julia/packages/Functors/rlD70/src/walks.jl:106 [inlined]
[9] CachedWalk
@ ~/.julia/packages/Functors/rlD70/src/walks.jl:146 [inlined]
[10] execute(::Functors.CachedWalk{Functors.ExcludeWalk{Functors.DefaultWalk, DataType, typeof(Functors.isleaf)}, Functors.NoKeyword}, ::Foo)
@ Functors ~/.julia/packages/Functors/rlD70/src/walks.jl:38
[11] fmap(::Type, ::Foo; exclude::Function, walk::Functors.DefaultWalk, cache::IdDict{Any, Any}, prune::Functors.NoKeyword)
@ Functors ~/.julia/packages/Functors/rlD70/src/maps.jl:11
[12] fmap(::Type, ::Foo)
@ Functors ~/.julia/packages/Functors/rlD70/src/maps.jl:3
[13] top-level scope
@ REPL[59]:1
However if we use map we have
julia> r = [1,2,3];
julia> map(Float32, r)
3-element Vector{Float32}:
1.0
2.0
3.0
julia> fmap(Float32, r)
ERROR: MethodError: no method matching Float32(::Vector{Int64})
Closest candidates are:
(::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number}
@ Base char.jl:50
(::Type{T})(::Base.TwicePrecision) where T<:Number
@ Base twiceprecision.jl:266
(::Type{T})(::Complex) where T<:Real
@ Base complex.jl:44
...
Stacktrace:
[1] (::Functors.ExcludeWalk{Functors.DefaultWalk, DataType, typeof(Functors.isleaf)})(::Function, ::Vector{Int64})
@ Functors ~/.julia/packages/Functors/rlD70/src/walks.jl:106
[2] (::Functors.CachedWalk{Functors.ExcludeWalk{Functors.DefaultWalk, DataType, typeof(Functors.isleaf)}, Functors.NoKeyword})(::Function, ::Vector{Int64})
@ Functors ~/.julia/packages/Functors/rlD70/src/walks.jl:146
[3] execute(::Functors.CachedWalk{Functors.ExcludeWalk{Functors.DefaultWalk, DataType, typeof(Functors.isleaf)}, Functors.NoKeyword}, ::Vector{Int64})
@ Functors ~/.julia/packages/Functors/rlD70/src/walks.jl:38
[4] fmap(::Type, ::Vector{Int64}; exclude::Function, walk::Functors.DefaultWalk, cache::IdDict{Any, Any}, prune::Functors.NoKeyword)
@ Functors ~/.julia/packages/Functors/rlD70/src/maps.jl:11
[5] fmap(::Type, ::Vector{Int64})
@ Functors ~/.julia/packages/Functors/rlD70/src/maps.jl:3
[6] top-level scope
@ REPL[52]:1
Is there any reason why fmap has a different behaviour than map when applied to Arrays?
How can I do that otherwise?
Thanks,
Ferréol