Transcript from the "Pipelines & Review" Lesson
>> Richard Feldman: So let's talk about pipelines. So let's say I have a list of numbers, 2, 4, 6, and I want to call List.filter on it. I say List.filter where I'm gonna give it an anonymous function. It takes an x, an x is less than 5. In other words, I only want to keep these elements if x is less than 5.
[00:00:18] I also say, you know what? Not only do I wanna do that filtering operation, I also wanna reverse it when I'm done. So call List.reverse on the result of List.filter passing that function and that list. So this is one way I can write this. It's kind of a lot of parentheses going on there.
[00:00:34] This is another way I could write this. These two expressions are completely equivalent. The difference is that this second one has been written in what is known as pipeline style. So the way that pipeline style works is you can think of it as similar to Unix pipe. So what it's saying is, start with 2, 4, 6.
[00:00:56] And pipe that to List.filter x, where x is less than 5. In other words, take this thing right here and make it be the last argument to this next thing. So List.filter this, and then this becomes the final argument that gets added on to the end here. And then do it again, take the result of that expression.
[00:01:15] And pipe it to List.reverse. So the output of the previous step gets used as an additional argument to the next step. We could do that again, List.map negate. In other words, negate all of the numbers in this list that we've been building up to so far. So first do this.
[00:01:31] Then filter it, take that list, reverse it. Take that list and map negate over each of its elements. We can keep going with this as far as we want. And take List.head of the results of that. So grab the first one and give us back a maybe. We can do this as many times as we want.
[00:01:49] The pipe is actually not a special language keyword, it's an operator that works as a function that works because of partial application. So essentially it relies on the fact that List.filter passing this anonymous function. This expression right here to the right of the pipe gives us back a function that takes a list of numbers, and then returns a list of numbers.
[00:02:13] And then this next and then so it gives it this listed number so cool. Now we return a list of numbers, pass that to List.reverse which expects a list of whatever is and returns a list of whatever's, and so on and so forth throughout the pipeline. So especially as you get more steps in a sequence, this can be a nicer way of writing out something like this, than doing it with all the parenthesis.
[00:02:36] Worth noting though that also a lot of the time, an even better solution to this is just good old fashioned, giving things names. Like saying, reversed equals and then maybe taking the first half of this pipeline, and then breaking it up into two different operations where the second one is calling some functions on reversed which sort of got us to that stage in the process.
[00:02:59] This is something that comes up in particular with what we're gonna learn in maybe the section after next. But for now it's enough to know that this is just a technique we can use to express the same thing. By the way, when I said that this right here was exactly equivalent to the above, I really mean that it really is equivalent as in, the Elm compiler will actually rewrite this into the equivalent of calling the functions directly.
[00:03:46] Questions about pipelines. All right, so to review. We first talked about List.head, and how we can call that on a series of, let's say numbers. And that'll give us back a maybe that represents either the first elements in the list. Or if there was none, nothing. We talked about maybe, and how it has a type variable.
[00:04:06] So, type Maybe v = Just v or Nothing. Talked about how that v could be anything, could be Val, Ellen, whatever we wanna call it. The important part is that it's lower case indicating that it's a type variable, and not a concrete type like we've been dealing with up to this point.
[00:04:18] We talked about the general concept of type variables, and how they can relate to one another. So when we say head takes a list of elements, and then returns a Maybe element. That means that whatever type of list it is, that's the type of Maybe we're gonna get back.
[00:04:32] And finally, we talked about pipelines and how you can pipe things to various different operations. And it will take the result of the previous step, and pass it as an additional argument to the next step.