Skip to content

Instantly share code, notes, and snippets.

@chris-martin
Last active September 16, 2017 20:16
Show Gist options
  • Save chris-martin/9a47b9f895223975be461f3887ad320a to your computer and use it in GitHub Desktop.
Save chris-martin/9a47b9f895223975be461f3887ad320a to your computer and use it in GitHub Desktop.

Let's say we want to test whether the list [1,2,3,4,5] contains 2.

We could do this by turning the list of integers [1,2,3,4,5] into a list of Booleans [False, True, False, False, False] indicating, for each element in the original list, whether it is equal to 2.

λ> x = map (== 2) [1..5]

And then we can loop over it with foldr, starting with a base value of False and taking the Boolean or with each value in x. So if any of the values in x is True, then the result will end up True, telling us that the element is in the list.

λ> foldr (||) False x
True

And we see that it is.

Don't worry too much about the details of foldr; what's next is the interesting part. We can use the :sprint command in the REPL to inspect the value of x without performing any further evaluation:

λ> :sprint x
x = False : True : _

It shows us that x consists of:

  1. False (because 1 /= 2), then
  2. True (because 2 == 2), and then
  3. ... an unspecified remainder of the list.

The rest of x never got evaluated. In other words, the loop terminated early.

This is because the function we used with foldr we used to combine the values was ||. Once the value accumulated in the loop became True, it evaluated to True || 📦, where 📦 is the result of folding over the rest of the list. Since True || 📦 is always True no matter what 📦 is, evaluation can just stop there and output True.

If we print x to the REPL, we force evaluation of the rest of it. And we see that it is in fact what we expected:

λ> x
[False,True,False,False,False]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment