Search code examples
crystal-lang

Using a Proc accepting a Tuple containing unions


When trying to use a Proc with Tuple containing union types as an argument:

proc = ->(t : Tuple(Float64|Int32, Float64|Int32)){ t[0] + t[1] }
proc.call({1, 3})

I get this error:

type must be Tuple(Float64 | Int32, Float64 | Int32), not Tuple(Int32, Int32)

Isn't the tuple {1,3} already of that type? If not, how can I pass a tuple of that type? Or are tuples containing union types not supported when using a Proc?


Solution

  • Unfortunately you have to explicitly cast it for now:

    proc = ->(t : {Float64|Int32, Float64|Int32}){ t[0] + t[1] }
    proc.call({1, 3}.as({Float64|Int32, Float64|Int32}))
    

    You can tidy it up a little bit with an alias:

    alias Point = {Float64|Int32, Float64|Int32}
    proc = ->(t : Point){ t[0] + t[1] }
    proc.call({1, 3}.as(Point))
    

    Or maybe even create a dedicated value type:

    record Point, x : Float64|Int32, y : Float64|Int32
    proc = ->(t : Point){ t.x + t.y }
    proc.call(Point.new(1, 3))