Skip to content

Correct way to reconstruct an instance of an object #3

Closed
@willtebbutt

Description

@willtebbutt

The following (unsurprisingly) yields an error:

struct Foo
    a::Float64
    b::String
end

@functor Foo (a,)

x, re = functor(Foo(5.0, "hi"))

julia> re(x)
ERROR: MethodError: no method matching Foo(::Float64)
Closest candidates are:
  Foo(::Float64, ::String) at REPL[34]:2
  Foo(::Any, ::Any) at REPL[34]:2
Stacktrace:
 [1] (::var"#22#23")(::NamedTuple{(:a,),Tuple{Float64}}) at /Users/willtebbutt/.julia/dev/Functors/src/functor.jl:12
 [2] top-level scope at REPL[37]:1

You can imagine this kind of thing cropping up, where only a subset of the fields of an object are considered "parameters", but you do need to have access to the others to make an instance of the object.

Is the intended way to handle this to define my own method of functor as follows:

function Functors.functor(x::Foo)
    function reconstruct_Foo(xs)
        return Foo(xs.a, x.b)
    end
    return (a = x.a,), reconstruct_Foo
end

julia> x, re = functor(Foo(5.0, "hi"))

julia> re(x)
Foo(5.0, "hi")

julia> fmap(Float32, Foo(5.0, "hi"))
Foo{Float32}(5.0f0, "hi")

?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions