X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=exercises%2Fassignment4.mdwn;h=3786a61ba832b7ddc934ae35ebb79f8526b4a7ee;hp=8bbeffe49a72306d0f9e4d583f0bfd164b22b3d3;hb=937c6218cf7d2b947b3966342a38d883853a6492;hpb=97c5d76f0ec754836103c4b2a3f86efb670588db diff --git a/exercises/assignment4.mdwn b/exercises/assignment4.mdwn index 8bbeffe4..3786a61b 100644 --- a/exercises/assignment4.mdwn +++ b/exercises/assignment4.mdwn @@ -62,6 +62,7 @@ For instance, `fact 0 ~~> 1`, `fact 1 ~~> 1`, `fact 2 ~~> 2`, `fact 3 ~~> let empty = \f n. n in let cons = \x xs. \f n. f x xs in let empty? = \xs. xs (\y ys. false) true in + let head = \xs. xs (\y ys. y) err in let tail = \xs. xs (\y ys. ys) empty in let append = Y (\append. \xs zs. xs (\y ys. (cons y (append ys zs))) zs) in let take_while = Y (\take_while. \p xs. xs (\y ys. (p y) (cons y (take_while p ys)) empty) empty) in @@ -74,8 +75,14 @@ For instance, `fact 0 ~~> 1`, `fact 1 ~~> 1`, `fact 2 ~~> 2`, `fact 3 ~~> Here are some tips for getting started. Use `drop_while`, `num_equal?`, and `empty?` to define a `mem?` function that returns `true` if number `x` is a member of a list of numbers `xs`, else returns `false`. Also use `take_while`, `drop_while`, `num_equal?`, `tail` and `append` to define a `without` function that returns a copy of a list of numbers `xs` that omits the first occurrence of a number `x`, if there be such. You may find these functions `mem?` and `without` useful in defining `set_cons` and `set_equal?`. Also, for `set_equal?`, you are probably going to want to define the function recursively... as now you know how to do. + Some comments comparing this exercise to *The Little Schemer*, and Scheme more generally: -7. Linguists often analyze natural language expressions into trees. We'll need trees in future weeks, and tree structures provide good opportunities for learning how to write recursive functions. Making use of our current resources, we might approximate trees as follows. Instead of words or syntactic categories, we'll have the nodes of the tree labeled with Church numbers. We'll think of a tree as a list in which each element is itself a tree. For simplicity, we'll adopt the convention that a tree of length 1 must contain a number as its only element. + * The `set_equal?` you're trying to define here is like `eqset?` in Chapter 7 of *The Little Schemer*, and `set_cons x xs` would be like `(makeset (cons x xs))`, from that same chapter. + * `mem?` and `without` are like the `member?` and `rember` functions defined in Chapter 2 and 3 of *The Little Schemer*, though those functions are defined for lists of symbolic atoms, and here you are instead defining them for lists of numbers. *The Little Schemer* also defines `multirember`, which removes all occurrences of a match rather than just the first; and `member*` and `rember*` in Chapter 5, that operate on lists that may contain other, embedded lists. + * The native Scheme function that most resembles the `mem?` you're defining is `memv`, though that is defined for more than just numbers, and when that `memv` finds a match it returns a *list* starting with the match, rather than `#t`. + + +7. Linguists often analyze natural language expressions into **trees**. We'll need trees in future weeks, and tree structures provide good opportunities for learning how to write recursive functions. Making use of our current resources, we might approximate trees as follows. Instead of words or syntactic categories, we'll have the nodes of the tree labeled with Church numbers. We'll think of a tree as a list in which each element is itself a tree. For simplicity, we'll adopt the convention that a tree of length 1 must contain a number as its only element. Then we have the following representations: @@ -102,7 +109,7 @@ For instance, `fact 0 ~~> 1`, `fact 1 ~~> 1`, `fact 2 ~~> 2`, `fact 3 ~~> Some limitations of this scheme: there is no easy way to label an inner, branching node (for example with a syntactic category like VP), and there is no way to represent a tree in which a mother node has a single daughter. - When processing a tree, you can test for whether the tree is a leaf node (that is, contains only a single number), by testing whether the length of the list is 1. This will be your base case for your recursive definitions that work on these trees. + When processing a tree, you can test for whether the tree is a leaf node (that is, contains only a single number), by testing whether the length of the list is 1. This will be your base case for your recursive definitions that work on these trees. (You'll probably want to write a function `leaf?` that encapsulates this check.) Your assignment is to write a Lambda Calculus function that expects a tree, encoded in the way just described, as an argument, and returns the sum of its leaves as a result. So for all of the trees listed above, it should return `1 + 2 + 3`, namely `6`. You can use any Lambda Calculus implementation of lists you like.