Introduction to Elm, v2 Type Variables
Transcript from the "Type Variables" Lesson
>> Richard Feldman: So this kind of begs the question, what is the type of List.head? I mean, it can't be just one of these, right? It can't be List.head takes a list of strings and returns a navy string, or a List.float and returns a navy float, or even list.bool and returns a navy bool, because it's all of those.
[00:00:16] Depending on how it's used, it ends up with a different type parameter. How does that work? So the answer is that it has what's known as a type variable. So, this the type of a List.head. It's list, elem, with a lower case E to maybe elem, which also has a lower case E.
[00:00:37] So, here elem is a type variable. It's a name that I choose, I could've chosen any name that I want, I could've also annotated it this way, list of elem maybe even just list of v or maybe v. All of this type annotations do exactly the same thing.
[00:00:51] The critical piece is that A, it's lower case. So the lowercase part means it's a variable, not a concrete type like the uppercase types that we've normally seen in type annotations up to this point. And B, that they agree. So this is saying, I have a list of somethings and I gives back maybe of the same sort of thing.
[00:01:09] Same thing with val, if I've chosen the name val here that's all well and good, but this one needs to agree with that. It's saying that whatever that type turns out to be, when I actually call this function, that's the maybe I'm gonna get back and that's how we can have this flexibility.
[00:01:23] Where if I give it a list of strings, it gives me back a maybe string. If I give it a list of floats it gives me back a maybe float and so forth. But I can pick any number of different names here that I want. These are called type variables these things in blue here the lowercase one is a type variable.
[00:01:39] Okay, so these come up in a number of different circumstances. So list dot reverse is another one this takes a list of, again here I chose, I happen to choose the name item, could've also chosen val or v or elem. So takes a list of items and returns a list of the same type of items.
[00:01:55] So if I give list out reversal with some strings, it will give me back also a list of strings, just in reverse order. I can also use that on numbers if I want, that's totally fine. I can also use List.singleton, which takes a single value and then, returns a list of those values.
[00:02:13] It basically just wraps it up. It's the same thing as putting square brackets around it. Except, in the form of a function. Yeah, and here's an example of List.singleton. Cool, okay, so this is List.head. So what is the type of Maybe? How is that actually defined as a custom type?
[00:02:33] So we could say type Maybe = Just and Nothing, but we know that it's not just an enumeration. There actually is some data being held onto there. And that data is represented as a type variable. So it says type Maybe val = Just val / Nothing. In other words, what's storied in the Just is not fixed, it's not a string, it's not an int, it's not a float, it depends entirely on the Maybe, it's a little bit more flexible than that.
[00:03:00] So this allows us to have Maybes of different types, of different shapes. Maybe can be used on strings, on hints on faults, on whatever you want, depending on the circumstance. And because we a type variable up here as well, it says when I call List.head the type of this variant is going to end up depending on the elements in this list.
[00:03:21] If I call this .head with a list of strings, this maybe is going to hold on to just a string or nothing. Call floats to floats, just a float or nothing.