Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify union types #151

Open
lazarljubenovic opened this issue Feb 12, 2017 · 3 comments
Open

Clarify union types #151

lazarljubenovic opened this issue Feb 12, 2017 · 3 comments

Comments

@lazarljubenovic
Copy link
Contributor

I'm not sure if I'm missing something obvious, but the section on Union types starts mentioning Yes and No, and keeps dragging it through all examples without ever explaining what this could be.

Having never written anything in Elm myself and this being my first time going though the tutorial, I cannot imagine what would type Yes and No be.

I understand the basic idea about union types, but the concrete example looks like it could use some improving.

@supermacro
Copy link

supermacro commented Feb 24, 2018

Hey @lazarljubenovic, I know this answer is coming in a year later but hopefully it still helps.

At least anyone else reading this later will have an explanation.

Another way to think of Union types is to think of them as sets.

The set of all integers is [-infinity ... -1, 0, 1, 2, 3, ..., +infinity]

If you were to model this in elm, the type would be.

type Integer = -99999 | -99998 | ... | -3 | -2 | -1 | 0 | 1 | 2 | 4 | ....9999999

I don't know if this would even compile but this is how you should be thinking of Union types.

The point is, left hand side of the = sign is the type and the right hand sign of the = sign is the set of potential values that the type represents.

So an integer can be -9999, or 0, or 84894, or whatever else is in the "set" (or more precisely, "type") called integer.

Here is the type definition for Maybe - a native type built into the Elm language.

type Maybe a = Just a | Nothing

This is useful when you are not sure if the a value exists at all.

hasAValue : Maybe Int -> Bool
hasAValue unknown =
    case unknown of 
        Nothing -> False

    case Just value -> True


-- hasAValue Maybe Nothing  -> False
-- hasAValue Maybe 12 -> True

Another realistic example would be a linked list:

Here's the type definition in elm for a Singly Linked List

type LinkedList a = 
  Null
  | Node a (LinkedList a)

So a linked list can be either Null OR a Node with a value and a pointer to a next node.

Notice that I defined LinkedList with a type variable a. This is so that I can have linked lists of different kinds ..

  • Linked lists of Ints
  • Linked lists of strings
  • Linked lists of ...... anything!

I could have been more strict and defined it as type LinkedList Int = ...

anyways ...

So if we had a LinkedList of Ints, the type would be LinkedList Int

[  12 | --> [ 99 | --> [ 5 | Null ] ] ]

And the values would look as follows:

myList : LinkedList Int
myList = Node 12 (Node 99 (Node 5 (Null))) 

Hope I didn't scare anyone off with the fact that LinkedLists are defined recursively!


@sporto Let me know if you would like me to submit a PR based on my explanation here.

@lazarljubenovic
Copy link
Contributor Author

Thanks for the reply! 😄 Elm is for years something that I want to learn, plan to learn, I preach it to everyone but I have never really sat down and did something serious. Here am I, a year later, still on the same level, with no new experience, yet thinking about Elm every week :(

Anyway, my memory is a bit rusty by this point (obviously), but reading my question and your answer, I still didn't catch the aswer. I specifically ask about Yes and No, but you don't mention them.

I get what a union type is, but I just couln't wrap my head around what exactly could Yes and No be. Are they Elm built-ins? Are they strings? Enumerations?

@sporto
Copy link
Owner

sporto commented Feb 24, 2018

@lazarljubenovic I will try to explain the way I understand what these are.

Many languages let you define an "atom" type. e.g. in ruby you can use symbols e.g. :hello, in Elixir is called an atom :hello. You can think about this like a constant. the compiler takes this value and defines a constant. :hello is always equal to another :hello.

Yes or No in Elm are like constants too. When you define a type in Elm, Yes is always the same as Yes.

However in Elm you can reuse the same name in different modules. e.g in one module you can have type Answer = Yes | Nope and in another module you could have type Response = Yes | No. In this case Yes is different between those modules. The compiler will error if you try to import both as it is ambiguous which one do you want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants