Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to "cast" union types elm

Tags:

elm

Lets's say I have two type aliases:

type alias A = {...}
type alias B = {...}

and a union type

type Content = A | B

and a model type

type alias Model= {cont : Content, ...}

init : Content -> Model
init cont = {cont = cont, ...}

How do I pass a record of type A to init.

a : A
a = {...}
init a 

throws the following error:

Detected errors in 1 module.
## ERRORS in Main.elm ##########################################################

-- TYPE MISMATCH ------------------------------------------------------ Main.elm

The 1st argument to function `init` has an unexpected type.

78|               init e
                       ^
As I infer the type of values flowing through your program, I see a conflict
between these two types:

    Content

    A

I would imagine that A is a kind of "subtype" of Content. I can't just write

a:Content
a = {...}
init a

because some of the logic does case analysis on Content

like image 605
Michiel Ariens Avatar asked Mar 14 '23 23:03

Michiel Ariens


1 Answers

Elm's union types are so-called discriminated unions (or tagged unions). The discriminating part is a tag or constructor. In this case I think you want:

type Content = TagA A | TagB B

Note that the first capitalised name is the tag, and anything else is other types or type variables.

Now you can do:

a : A
a = { ... }
init (TagA a)

Within init you can distinguish the two types by doing:

init content =
  case content of
    TagA a -> ...
    TagB b -> ...
like image 91
Apanatshka Avatar answered Mar 22 '23 23:03

Apanatshka