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

hugomg

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?

Leo White

A slight variation on what you already have. Instead of using a continuation, just provide a function to generate a fresh state:

module State : sig

  type t

  val fresh : unit -> t

  val uniqueId : t -> int

end = struct

  type t = int ref 

  let fresh () = ref 0

  let uniqueId s = incr s; !s

end

let () =
  let x1 =
    let s = State.fresh () in
    let i = State.uniqueId s in
      i
  in
    print_int x1;
    print_newline () (* Prints 1 *)

let () =
  let x2 =
    let s = State.fresh () in
    let i = State.uniqueId s in     (* 1 *)
    let j = State.uniqueId s in     (* 2 *)
      i + j
  in
    print_int x2;
    print_newline () (* Prints 3 *)

This is a common approach to handling environments in compilers, which looks a lot like what you are trying to do. It doesn't thread the state through implicitly, since OCaml doesn't support implicit parameters. However if you only require a single such "environment" parameter then it is not too onerous to add it to all the appropriate functions.

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

How to make a nested toSet in scala in an idiomatic way?

来自分类Dev

Alternative way to implement state machines in VHDL

来自分类Dev

OCaml中的“`”是什么?

来自分类Dev

OCaml模拟模块生成

来自分类Dev

Rails proper way to do multiple relationships

来自分类Dev

OCaml语法问题

来自分类Dev

OCaml中的输入错误

来自分类Dev

OCaml-撤消列表

来自分类Dev

How do I get Ruby to search for a pattern on the tail of a local file?

来自分类Dev

Is there a way to do nested generate statements in Verilog?

来自分类Dev

Scala: Most idiomatic way to conditionally execute one Future depending on another?

来自分类Dev

Most idiomatic way to mix synchronous, asynchronous, and parallel computation in a scala for comprehension of futures

来自分类Dev

Idiomatic multiindex column assignment in pandas

来自分类Dev

A proper way to do a WorkerQueue in NodeJs fassion?

来自分类Dev

Is there a better way to do an "unravel" function in python?

来自分类Dev

Is there a way to do ROLLUP or CUBE in R like in sql?

来自分类Dev

OCaml的类型A。at`语法

来自分类Dev

Basic Ocaml: How do I compile this?

来自分类Dev

OCaml优先级

来自分类Dev

OCaml中的参数化

来自分类Dev

Implicit conversion sequence

来自分类Dev

在ocaml中解析yaml

来自分类Dev

OCaml |>运算符

来自分类Dev

A good and idiomatic way to use GCC and clang __attribute__((cleanup)) and pointer declarations

来自分类Dev

OCaml属性

来自分类Dev

Ramda Curry with Implicit Null

来自分类Dev

How to delete safari History, Cache, Cookies, Top sites, Saved state and local storage in cocoa app(Mac) in objective c

来自分类Dev

OCaml缺点

来自分类Dev

Is there a way to cause chrome/ie/firefox to reload the local "hosts" file without restarting the app?

Related 相关文章

热门标签

归档