From: Jim Pryor Date: Sun, 5 Dec 2010 18:15:01 +0000 (-0500) Subject: commentary on ass6 solutions X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=commitdiff_plain;h=ed113b80c941bdd33e09c6c5d5f8f46958542d1f;ds=inline commentary on ass6 solutions Signed-off-by: Jim Pryor --- diff --git a/assignment6.mdwn b/assignment6.mdwn index 82aee95f..a31cbf8a 100644 --- a/assignment6.mdwn +++ b/assignment6.mdwn @@ -24,7 +24,7 @@ your solution). You'll need to define a computation monad type, unit, bind, and lift2. We encourage you to consider this hint: [[hints/Assignment 6 Hint 1]]. -
See our [commentary](/hints/assignment_6_commentary) on your solutions.
+ See our [commentary](/hints/assignment_6_commentary) on your solutions. 2. Prove that your monad satisfies the monad laws. First, give diff --git a/hints/assignment_6_commentary.mdwn b/hints/assignment_6_commentary.mdwn index df757cbc..d58a7fce 100644 --- a/hints/assignment_6_commentary.mdwn +++ b/hints/assignment_6_commentary.mdwn @@ -19,13 +19,15 @@ Whoops. That will work for the cases you're probably thinking about. For instanc and you'll get back an `int state` that when applied to a starting count of `0` yields the result `(6, 2)`---that is, the result of the computation was 6 and the number of operations was 2. -However, there are several problems here. First off, you shouldn't name your function `lift`, because we're using that name for a function that's interdefinable with `bind` in a specific way. Our canonical `lift` function (also called `mapM` and `liftM` in Haskell) is: +However, there are several problems here. First off, you shouldn't name your function `lift2`, because we're using that name for a function that's interdefinable with `bind` in a specific way. Our canonical `lift2` function is: let lift2 (f : 'a -> 'b -> 'c) (u : 'a state) (v : 'b state) : 'c state = bind u (fun x -> bind v (fun y -> unit (f x y)));; +(Haskell calls this `liftM2`, and calls our `lift` either `liftM` or `mapM`.) + OK, so then you might call your function `loft2` instead. So what? The remaining problem is more subtle. It's that your solution isn't very modular. You've crafted a tool `loft2` that fuses the operation of incrementing the count with the behavior of our `lift2`. What if we needed to deal with some unary functions as well? Then you'd need a `loft1`. What if we need to deal with some functions that are already monadic? Then you'd need a tool that fuses the count-incrementing with the behavior of `bind`. And so on.