edits
authorChris <chris.barker@nyu.edu>
Wed, 8 Apr 2015 16:50:27 +0000 (12:50 -0400)
committerChris <chris.barker@nyu.edu>
Wed, 8 Apr 2015 16:50:27 +0000 (12:50 -0400)
code/Juli8-v1.5.tgz [new file with mode: 0644]
index.mdwn
juli8.mdwn
topics/week8_monads_and_modules.mdwn
topics/week9_monad_transformers.mdwn

diff --git a/code/Juli8-v1.5.tgz b/code/Juli8-v1.5.tgz
new file mode 100644 (file)
index 0000000..705ca62
Binary files /dev/null and b/code/Juli8-v1.5.tgz differ
index 8f4a410..5e1c25d 100644 (file)
@@ -167,9 +167,11 @@ Practical advice for working with OCaml and/or Haskell (will be posted someday);
 
 (**Week 9**) Thursday April 2
 
-> Updated notes on [[Installing and Using the Juli8 Libraries|/juli8]] on Sun 5 April. The major change is to make the Monad libraries easier to use. Now you can just use `Monad.Reader(struct type env = ... end)`; you don't need to furthermore ask for the `M` submodule of that generated module. Relatedly, the `List` and `Monad.List` modules are now different; the former has lots of list-related functions and the latter only the monadic interface. Similarly for `Option` and `Monad.Option`.
+> Updated notes on [[Installing and Using the Juli8 Libraries|/juli8]] on Sun 5 April. Continued to fix some bugs and improve the monad transformers. Latest version posted Tuesday evening, 7 April: [[v1.5|/code/Juli8-v1.5.tgz]].
 
-> Small bug fix to Juli8 on Mon 6 April.
+<!--
+The major change is to make the Monad libraries easier to use. Now you can just use `Monad.Reader(struct type env = ... end)`; you don't need to furthermore ask for the `M` submodule of that generated module. Relatedly, the `List` and `Monad.List` modules are now different; the former has lots of list-related functions and the latter only the monadic interface. Similarly for `Option` and `Monad.Option`.
+-->
 
 > Topics: [[Using the OCaml Monad library|/topics/week9_using_the_monad_library]]; [[Programming with mutable state|/topics/week9_mutable_state]]; [[A State Monad Tutorial|/topics/week9_state_monad_tutorial]]; [[Using multiple monads together|/topics/week9_monad_transformers]]; [[Homework for weeks 8-9|/exercises/assignment8-9]]
 
index b12de03..b60816d 100644 (file)
@@ -91,7 +91,7 @@ Below, we'll give instructions on how to install Juli8 into your existing OCaml
 
         #use "juli8.ml";;
 
-4. Next create a folder in your `$HOME` directory named `.juli8`. **Download the Juli8 code from [[here|/code/Juli8-v1.4.tgz]].** That link will no doubt be updated frequently in April and May 2015. The current version is: 1.4, posted 6 April 2015. Copy the contents of the `Juli8` folder that you downloaded into the `$HOME/.juli8` folder that you created. (So `$HOME/.juli8` should contain folders `haskell`, `ocaml`, and so on.)
+4. Next create a folder in your `$HOME` directory named `.juli8`. **Download the Juli8 code from [[here|/code/Juli8-v1.5.tgz]].** That link will no doubt be updated frequently in April and May 2015. The current version is: 1.5, posted 7 April 2015. Copy the contents of the `Juli8` folder that you downloaded into the `$HOME/.juli8` folder that you created. (So `$HOME/.juli8` should contain folders `haskell`, `ocaml`, and so on.)
 
     Now whenever you start up OCaml, the Juli8 OCaml libraries (including their monad components, which we'll be making extensive use of) will automatically be loaded. <!-- If later you want to load Oleg's Delimcc library, type `#load "delimcc.cma";;` then use the `Delimcc` module. -->
 
index e7372d3..2737ed5 100644 (file)
@@ -539,7 +539,7 @@ Here is some code showing how to generate the common monad modules, and also som
     module S = Monad.State(struct type store = int end) (* or any other implementation of stores *)
     S.(get,gets,put,modify) (* same additional interface as Haskell has; we'll explain them later *)
     module Ref = Monad.Ref(struct type value = string end) (* this is essentially a State monad, but with a different interface *)
-    Ref.(newref,deref,change)
+    Ref.(newref,getref,putref)
     module W = Monad.Writer(struct type log = string let empty = "" let append = (^) end) (* or any other implementation of logs *)
     W.(listen,listens,tell,censor)
     module E = Monad.Error(struct type err = string exception Exc = Failure end) (* or other specifications of type err and exception Exc of err *)
index ff47d06..f9da05a 100644 (file)
@@ -151,31 +151,28 @@ When Option is on the inside, on the other hand, as in SO, failure means the who
        Exception: Failure "bye".
 -->
 
-<!--
 Here's an example wrapping Option around List, and vice versa:
 
        # module LO = Monad.List.T(Monad.Option);;
-       # module OL = Monad.Option.T(Monad.List);;
-        # let plus = ???;;
-       # OL.(run (plus mzero mid 20 >>= fun i -> mid (i+10)));;
+       # module OL = Monad.Option.P(Monad.List);; (* we use the `.P` transformer to hoist List's ++ operation *)
+       # OL.(run (mzero ++ mid 20 >>= fun x -> mid (x+10) ));;
        - : int OL.result = [Some 30]
 
 When List is on the inside, the failed results just got dropped and the computation proceeds without them.
 
-       # LO.(run ((++) (hoist Monad.Option.mzero) (mid 20) >>= fun i -> mid (i+10)));;
+       # LO.(run (hoist Monad.Option.mzero ++ mid 20 >>= fun x -> mid (x+10) ));;
        - : int LO.result = None
 
-On the other hand, when Option is on the inside, as in LO, failures (which we represent by `mzero`s from the Option monad, here `hoist Monad.Option.mzero`, not the List monad's own `mzero`) abort the whole computation.
+On the other hand, when Option is on the inside, as in LO, failures (which we again represent by `mzero`s from the Option monad, not the List monad's own `mzero`; but here since it's the inner monad we need to `hoist Monad.Option.mzero`) abort the whole computation. (If you instead used the List monad's `mzero`, it'd be ignored by `++` and you'd end with just `Some [30]`.)
 
-This is fun. Notice the difference it makes whether the second `++` is native to the outer `Monad.List`, or whether it's the inner `Monad.List`'s `++` hoisted into the outer wrapper:
+This is fun. Here is a List around a List. Notice the difference it makes whether the second `++` is native to the outer `Monad.List`, or whether it's the inner `Monad.List`'s `++` hoisted into the outer wrapper:
 
        # module LL = Monad.List.T(Monad.List);;
 
-       # LL.(run((++) (mid 1) (mid 2) >>= fun i -> (++) (mid i) (mid (10*i)) ));;
+       # LL.(run(mid 1 ++ mid 2 >>= fun x -> mid x ++ mid (10*x) ));;
        - : int LL.result = \[[1; 10; 2; 20]]
-       # LL.(run((++) (mid 1) (mid 2) >>= fun i -> hoist L.((++) (mid i) (mid (10*i)) )));;
+       #  LL.(run(mid 1 ++ mid 2 >>= fun x -> hoist Monad.List.(mid x ++ mid (10*x)) ));;
        - : int LL.result = [[1; 2]; [1; 20]; [10; 2]; [10; 20]]
--->
 
 <!--
        # EL.(run((++) (throw "bye") (mid 20) >>= fun i -> mid (i+10)));;