SumTypes.jl
SumTypes.jl copied to clipboard
Using parametric struct and only defining the top level type makes it errors out
I'm trying to use SumTypes to replicate Rust Result type, and I expected the Result type to be able to carry all types. Here's the example code:
using SumTypes
#Rust like result type
@sum_type Result{A, B} begin
Ok{A}(::A)
Err{B}(::B)
end
#Some default errors
struct SequenceError{T}
prev::T
cur::T
end
struct Good
good::Int
end
function test(a) :: Result{Good, SequenceError}
if a
return Ok(Good(1))
else
return Err(SequenceError(1,1))
end
end
Somehow if my test function tries to return SequenceError it errors out with cannot convert error:
julia> test(true)
Ok(Good(1))::Result{Good, SequenceError}
julia> test(false)
ERROR: MethodError: Cannot `convert` an object of type
Result{Uninit,SequenceError{Int64}} to an object of type
Result{Good,SequenceError}
Closest candidates are:
convert(::Type{<:Result{A, B}}, ::Result{Uninit, B}) where {A, B}
@ Main ~/.julia/packages/SumTypes/Mrn3L/src/sum_type.jl:197
convert(::Type{T}, ::T) where T
@ Base Base.jl:84
convert(::Type{Result{A, B}}, ::Result{Uninit, B}) where {A, B}
@ Main ~/.julia/packages/SumTypes/Mrn3L/src/sum_type.jl:196
...
Stacktrace:
[1] test(a::Bool)
@ Main ~/workdir/nanoavionics/result.jl:24
[2] top-level scope
@ REPL[59]:1
But if I fully specify the type then it works:
julia> function test2(a) :: Result{Good, SequenceError{Int}}
if a
return Ok(Good(1))
else
return Err(SequenceError(1,1))
end
end
test2 (generic function with 1 method)
julia> test2(true)
Ok(Good(1))::Result{Good, SequenceError{Int64}}
julia> test2(false)
Err(SequenceError{Int64}(1, 1))::Result{Good, SequenceError{Int64}}
This is maybe https://github.com/MasonProtter/SumTypes.jl/issues/44, but I'm not that familiar with Julia type system yet
Hey sorry for the late reply @minecraft2048, I've been quite busy lately. Yeah, the problem here is that Julia's type system is invariant, not covariant (see this section of the docs: https://docs.julialang.org/en/v1/manual/types/#man-parametric-composite-types). The best I could do here I think is make it work with you writing :: Result{Good, <:SequenceError}. I'll see what I can do to support that.