SumTypes.jl icon indicating copy to clipboard operation
SumTypes.jl copied to clipboard

Using parametric struct and only defining the top level type makes it errors out

Open minecraft2048 opened this issue 2 years ago • 1 comments

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

minecraft2048 avatar Aug 14 '23 06:08 minecraft2048

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.

MasonProtter avatar Sep 01 '23 12:09 MasonProtter