X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=topics%2Fweek3_lists.mdwn;h=6f7c1e0fa6e1e5c6ae4a3b8a69b9078ef545e705;hp=00f1ffde495f6f4bdc92f757392cdf974560fc3c;hb=662133800820b7973cc895c474ec52e98b74a9b1;hpb=bf3bf7ab7f73a110ac9d0a901457e97d33e4bef8 diff --git a/topics/week3_lists.mdwn b/topics/week3_lists.mdwn index 00f1ffde..6f7c1e0f 100644 --- a/topics/week3_lists.mdwn +++ b/topics/week3_lists.mdwn @@ -48,7 +48,7 @@ Haskell also has an extension that permits you to iterate over multiple lists *i [ 10*x + y | y <- [4, 5, 6] | x <- [1, 2, 3] ] -will evaluate to `[14, 25, 36]`. If the lists are of unequal length, Haskell stops when it exhausts the first. These behaviors are similar to the `map2` function you defined in the week 1 homework. That also took an argument from each of several sequences in parallel. (The corresponding functions in Haskell are called `zip` and `zipWith`.) +will evaluate to `[14, 25, 36]`. If the lists are of unequal length, Haskell stops when it exhausts the shortest. These behaviors are similar to the `map2` function you defined in the week 1 homework. That also took an argument from each of several sequences in parallel. (The corresponding functions in Haskell are called `zip` and `zipWith`.) OCaml [permits lists comprehensions as an extension](http://stackoverflow.com/questions/27652428/list-comprehension-in-ocaml), and [so too does Scheme](http://srfi.schemers.org/srfi-42/srfi-42.html), but these are a bit harder to use. @@ -80,13 +80,15 @@ To translate that, first let's handle the iteration over the final list, that `x This looks like what we had before, except that now we have this free variable `y` in our lambda expression. Perhaps we can bind that variable inside a *larger* lambda expression, and then map (and filter) *that* larger lambda expression over the list that `y` is drawn from: - map (lambda y. map (lambda x. 10*x + y) [1, 2, 3]) $ filter (lambda y. y < 6) [4, 5, 6] + let + f match lambda y. map (lambda x. 10*x + y) [1, 2, 3] + in map f $ filter (lambda y. y < 6) [4, 5, 6] This gives us nearly what we want. It evaluates to: [[14, 24, 34], [15, 25, 35]] -Why? Because the `filter` expression at the end is restricting the domain that `y` ranges over to `[4, 5]`. Over this domain we are selecting a value to bind `y` to, and then evaluating the inner `map` expression with `y` so bound. With `y` bound to `4`, we get the result `[14, 24, 34]`. With `y` bound to `5`, we get the result `[15, 25, 35]`. These two results, in order, are the elements that make up the sequence which is the result of the outermost `map` expression. +Why? Because the `filter` expression at the end is restricting the domain that `y` ranges over to `[4, 5]`. Over this domain we are selecting a value to bind `y` to, and then evaluating the `map` expression inside `f` with `y` so bound. With `y` bound to `4`, we get the result `[14, 24, 34]`. With `y` bound to `5`, we get the result `[15, 25, 35]`. These two results, in order, are the elements that make up the sequence which is the result of the outermost `map` expression. One final twist is that our original list comprehension gives us a "flatter" result. In both Kapulet (and Haskell, modulo a few syntax adjustments), the list comprehension: