OCaml で状態モナドを実装しようとしていました (演習として)。私の実装は次のようになります。
module type MONAD_BUILDER =
sig
type 'a t
val return : 'a -> 'a t
val bind : 'a t -> ('a -> 'b t) -> 'b t
end;;
module MonadBuilder = functor (M: MONAD_BUILDER) ->
struct
let ( >>= ) = M.bind
let return = M.return
end;;
module StateM =
struct
type 'a state = { state: 's . 's -> ('a * 's) }
type 'a t = 'a state
let return x = { state = fun s -> (x, s) }
let bind m f =
let aux s =
let (x, s') = m.state s in
(f x).state s'
in { state = aux }
let run m x = fst (m.state x)
end;;
ファンクタを使用して状態型をモジュールにラップするという考えが気に入らないので、レコード フィールドに存在型を選択しました。上記の実装は機能しますが、実装中に問題が発生しましgetState
たsetState
。私はそれらを次のように実装しようとしました:
let getState = { state = fun s -> (s, s) }
let setState s = { state = fun _ -> ((), s) }
'a -> ('a * 'a)
と などの推論されたフィールド型'a -> (unit * 'a)
は、宣言された型より一般的ではないため、これは機能しません's . 's -> ('a * 's)
。なぜこれが起こっているのか理解していますが、レコードアプローチを使用してそれを機能させる別の方法があるかどうか疑問に思っていましたか?
ありがとう。
乾杯、アレックス