Nested Union Types

I have multiple union types that in turn belong to another union type like so:

type Foo = OneFoo | TwoFoo | ThreeFoo
type Bar = UnoBar | DosBar | TresBar
type Baz = Foo | Bar

I then have a function that matches on a Baz like so:

myFunct : Baz -> String
myFunct baz =
  case baz of
    OneFoo -> "One foo!"
    _ -> "who cares this is a silly pseudo example"

The compiler complains that

The pattern matches things of type:

Foo

But the values it will actually be trying to match are:

Baz

How do I overcome this?

You need to check if Baz is a Foo first.

case baz of
    Foo foo ->
        case foo of
            OneFoo ->
                ...

you can also do this to flatten the match a bit:

case baz of
    (Foo OneFoo) ->
                ...
1 Like

Seems obvious once it’s pointed out. Thanks.

Happy to help :slight_smile:

Celebrated too soon. Getting an error that Baz has too many arguments, expecting 0 but got 1.

This is a frequent mistake. When you say type Baz = Foo | Bar you are not creating a union type with type Foo and Bar inside but a tag Foo and a tag Bar. These two are values for the Baz.

In order to create a union that contains the type you need type Baz = FooTag Foo | BarTag Bar and then match with

case baz of
    FooTag foo ->
        case foo of
            OneFoo ->
                ...

Elm unions are tagged unions.

4 Likes

My bad - I overlooked you weren’t parameterizing the unions. I’m not sure how you match on that :stuck_out_tongue: sorry

That makes sense. Much appreciated.