I want to write some code that builds a thing using some local state. For example, consider the following code that uses local state to generate sequential integers:
type state = int ref
let uniqueId : (state -> int) =
fun s -> incr s; !s
let makeThings : ((state -> 'a) -> 'a) =
fun body -> body (ref 0)
let () =
let x1 = makeThings(fun s ->
let i = uniqueId s in (* 1 *)
i
) in
print_int x1; print_newline (); (* Prints 1 *)
(* Each makeThings callback gets its own local state.
The ids start being generated from 1 again *)
let x2 = makeThings(fun s ->
let i = uniqueId s in (* 1 *)
let j = uniqueId s in (* 2 *)
i + j
) in
print_int x2; print_newline (); (* Prints 3 *)
()
I'm curious if there is a way to make that s
state parameter inside the makeThings callback implicit, so that I don't need to type it over and over and so its guaranteed that all the uniqueId
calls get passed the same state prameter. For example, in Haskell you could use monads and do-notation to end up with code along the lines of
makeThings $ do
i <- uniqueId
j <- uniqueId
return (i + j)
In Ocaml, the only things that come to my mind are making s
a global variable (very undesirable) or trying to emulate Haskell's monadic interface, which I fear is going to be a lot of work and end up with slow code tahts also ugly due to a lack of do-notation. Is there an alternative I haven't thought of?