X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=exercises%2F_assignment7.mdwn;h=793a15e46c8715b5f99f5ac833f5c6e59fc96456;hp=d351b1b5009ff630fdeb82578f8a816697c00ed0;hb=2d9654c7eb13ddda627147563b2e937c67c7b8e3;hpb=4c61a5bce3d39fb96bbfac620debbceeaa9f9f5f diff --git a/exercises/_assignment7.mdwn b/exercises/_assignment7.mdwn index d351b1b5..793a15e4 100644 --- a/exercises/_assignment7.mdwn +++ b/exercises/_assignment7.mdwn @@ -1,50 +1,18 @@ -# Assignment 6 (week 7) +## Baby monads -## Evaluation order in Combinatory Logic +(Depends on lecture notes for safe division by zero.) -1. Give a term that the lazy evaluators (either the Haskell evaluator, -or the lazy version of the OCaml evaluator) do not evaluate all the -way to a normal form, i.e., that contains a redex somewhere inside of -it after it has been reduced. +Write a function `lift'` that generalized the correspondence between + +and `add'`: that is, `lift'` takes any two-place operation on integers +and returns a version that takes arguments of type `int option` +instead, returning a result of `int option`. In other words, `lift'` +will have type: - + (int -> int -> int) -> (int option) -> (int option) -> (int option) +so that `lift' (+) (Some 3) (Some 4)` will evalute to `Some 7`. +Don't worry about why you need to put `+` inside of parentheses. +You should make use of `bind'` in your definition of `lift'`: -2. One of the -[[criteria we established for classifying reduction strategies| -topics/week3_evaluation_order]] -strategies is whether they reduce subexpressions hidden under lambdas. -That is, for a term like `(\x y. x z) (\x. x)`, do we reduce to -`\y.(\x.x) z` and stop, or do we reduce further to `\y.z`? Explain -what the corresponding question would be for CL. Using either the -OCaml CL evaluator or the Haskell evaluator developed in the wiki -notes, prove that the evaluator does reduce expressions inside of -"functional" CL expressions. Then provide a modified evaluator that -does not perform reductions in those positions. - - - -3. In the previous homework, one of the techniques for controlling -evaluation order was wrapping expressions in a `let`: `let x = blah in -foo`, you could be sure that `blah` would be evaluated by the time the -interpreter considered `foo` (unless you did some fancy footwork with -thunks). That suggests the following way to try to arrive at eager -evaluation in our Haskell evaluator for CL: - - reduce4 t = case t of - I -> I - K -> K - S -> S - FA a b -> - let b' = reduce4 b in - let a' = reduce4 a in - let t' = FA a' b' in - if (is_redex t') then reduce4 (reduce_one_step t') - else t' - -Will this work? That is, will `reduce4 (FA (FA K I) skomega)` go into -an infinite loop? Run the code to find out, if you must, but write -down your guess (and your rationale) first. - - - + let bind' (u: int option) (f: int -> (int option)) = + match u with None -> None | Some x -> f x;;