Instructor: Let's play with filters. We'll do filter (myInList). The filter's coming in from our data.list. Let's fill out this function. We'll do _ > 1. If we look at the output, it's 2, 3, 4, and nil. This is all the values that are greater than 1 -- 2, 3, 4, and nil.
Now let's use mySmallIntList. We'll put that there, and we'll do < 1, so that will just return us nil. If it's less than or equal to 1, that's 1 and nil. If it's less than or equal to 2, that'd be 1, 2, and nil.
Let's make our own filter. We'll type filter, and that's got a type of forall a, and that takes a function of a -> Boolean. It takes a list of a, and it returns a list of a. On the next line, we'll do filter tick, with the inputs of P and L. That'll equal go, nil, and L. On the next line, we do where, and on the next line we'll do go, acc, nil.
Here we're pattern-matching, and that'll equal the reverse acc. On the next line, we'll do go acc, and we'll (X:Xs). The colon's an infix operator of cons, so it just splits our list. On the next line, we'll do |, which is guard, and P of X, and that equals go (X:acc Xs).
Look at the error on the right. We're missing a case expression, so we'll take care of that. We'll put |otherwise = go acc Xs. Let's change the function to <1, so that should return us nil. We'll explain exactly how our custom filter works.
When we call our function, we've got go. That gets passed to nil. The second value is L, which is our list. That's 1, 2 and nil. Now, we'll define go. Next we pattern match against go. We check if the second value is nil. In our case it isn't, so we're going to do go, acc, X of Xs. X, in our case, would be the 1, and the Xs would be the rest of the list, which is 2 and nil.
You can see how we're using colon, which is the infix operator of cons, to split our list. Now, we're going to use guards to see what to do with our values. We'll use our P, and the P's our function that we put in. That's _ < 1. The underscore is a value we pass into our function, so that's X, and currently that's 1.
We do, "Is 1 lower than 1?" That's nope, so it goes to the second case, which is otherwise, so that passes straight through. We're going to do a recursive call on go. We'll do go acc Xs. Our acc at the moment is nil, and our Xs is 2 and nil. Is our second value to go nil? No, so we'll go to the next part.
Our acc is nil, and we'll do X cons Xs, which makes the X 2 and the Xs nil. Now we do P X. Our X is 2, so is 2 greater than 1? Nope, so we'll go the next part, and we'll run go acc Xs. Our acc currently is nil, and our Xs is nil, so when we recurse on go again, our second value is nil. We'll hit this and we'll reverse our acc, which in our case is nil, so that returns nil.
Let's try something different. We'll change the value inside the function that we passed the filter. We'll do _ < 2. This will return us all the values in our list that are less than 2. Let's go through the function again. First time round, our X will be 1, and Xs will be 2 and nil.
This time, we're checking if X is less than 2. It is, so we'll cons X onto acc, so our X is 1 and our acc is nil. We'll put 1 onto nil, which gives us nil, 1. Our Xs will be 2 and nil. Background, our acc is nil and 1. Our second value was 2 and nil, so that X becomes 2 and Xs becomes nil.
We'll pass our X, which is 2, into our function. Is 2 less than 2? No, it's not, so we'll go into the otherwise. We'll run go acc -- at the moment which is nil and one -- and Xs, which is nil. Our second value is nil, so this time we'll reverse acc. In our case, it's nil and 1. The reverse of that is 1 and nil, which is the output that we get.
I've just noticed. We weren't actually using our function we created. Just to prove to you that it does work, we'll put a tick here. We'll filter out any values that are greater than 2. In this case, none are, so that returns nil. Now, we'll check if any of the values are less than or equal to 2. They all are, so that returns 1, 2, and nil.
Let's swap things up a little bit. We'll use myIntList, which is slightly larger. In this case, 3 and 4 aren't less than or equal to 2, so that doesn't return them. We get 1, 2, and nil. Finally, is greater than 1, and that will return us 2, 3, 4, and nil. Obviously, 1 isn't greater than 1.
There you go. You've made your own filter in Purescript.