add/update monad code
[lambda.git] / code / reader1.ml
diff --git a/code/reader1.ml b/code/reader1.ml
new file mode 100644 (file)
index 0000000..f9da961
--- /dev/null
@@ -0,0 +1,32 @@
+module E = struct
+  type bound = int
+  type env = char -> bound
+end
+module R_E = Monad.Reader(E)
+module R = R_E.M
+
+
+let env0 = fun var -> raise Not_found
+let insert var value e = fun sought -> if sought = var then value else e sought
+
+let getint (var : char) : int R.t = R.asks (fun e -> let x = e var in x)
+
+(* monadic versions of `x` and `y` *)
+let getx = getint 'x'
+let gety = getint 'y'
+
+(* monadic version of `y + x` *)
+let (expr1 : int R.t) = R.(gety >>= fun y -> getx >>= fun x -> mid (y + x))
+(* or *)
+let (expr1 : int R.t) = R.(map2 (+) gety getx)
+
+(* monadic version of `3 + x` *)
+let (expr2 : int R.t) = R.(map2 (+) (mid 3) getx)
+
+let letx xx body = R.(xx >>= fun x -> shift (insert 'x' x) body)
+
+(* monadic version of `let x = 2 in 3 + x` *)
+let (expr3 : int R.t) = R.(letx (mid 2) expr2)
+
+let res = R.run expr3 env0 (* will be 5 *)
+