13
我試圖在OCaml中實現狀態monad(作爲練習)。我的實現看起來是這樣的:OCaml中的狀態monad
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)
通用。我明白爲什麼會發生這種情況,但我想知道是否有另一種使用記錄方法使其工作的方式?
謝謝。
乾杯, 亞歷
感謝您的回答。 – Alex 2011-05-01 13:42:43