Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an idiomatic way to do implicit local state in OCaml?

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?

like image 991
hugomg Avatar asked Oct 16 '25 16:10

hugomg


1 Answers

Monads work in OCaml too. You can even have a do-notation, thanks to pa_monad_custom syntax extension. Although, in most cases having just an infix bind operator, i.e. >>= will be enough to write a fancy code.

like image 168
ivg Avatar answered Oct 18 '25 19:10

ivg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!