Skip to content

Instantly share code, notes, and snippets.

@VincentCordobes
Created April 6, 2019 19:19
Show Gist options
  • Save VincentCordobes/fff2356972a88756bd985e86cce03023 to your computer and use it in GitHub Desktop.
Save VincentCordobes/fff2356972a88756bd985e86cce03023 to your computer and use it in GitHub Desktop.
Simple Reader monad in OCaml
module Reader = struct
type ('e, 'a) t = Reader of ('e -> 'a)
let run = function
| Reader r -> r
let map f m = Reader (fun env -> f (run m env))
let bind f m = Reader (fun env -> run (f (run m env)) env)
let ( >>= ) m f = bind f m
let return x = Reader (fun _ -> x)
let ask () = Reader (fun env -> env)
let local f m = Reader (fun env -> run m (f env))
end
(* Example *)
type env = {
name: string;
age: int;
}
let to_string age name =
"name: " ^ name ^ "\nage: " ^ string_of_int age
let name env = env.name
let _ =
let open Reader in
let r =
return 24
|> map (fun x -> x + 1)
>>= (fun x -> ask () |> map name |> map (to_string x))
|> local (fun env -> {env with name="Vincent"})
in
let env = {name= "Jack"; age= 85} in
Printf.printf "%s\n" (run r env)
(* name: Vincent *)
(* age: 25 *)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment