比方說,我有一個選項列表:OCaml的:更高kinded多態性(抽象化了的模塊?)
let opts = [Some 1; None; Some 4]
我想這些轉換成列表的選項,使得:
- 如果列表包含
None
,結果爲None
- 否則,將收集各種整數。
這是比較簡單的寫這對於這種特殊情況下(使用Core和Monad
模塊):
let sequence foo =
let open Option in
let open Monad_infix in
List.fold ~init:(return []) ~f:(fun acc x ->
acc >>= fun acc' ->
x >>= fun x' ->
return (x' :: acc')
) foo;;
然而,作爲問題標題所暗示的,我真的很想抽象的過度型構造函數而不是專門用於Option
。 Core似乎使用一個仿函數來給出更高kinded類型的效果,但我不清楚我如何編寫要在模塊中抽象的函數。在Scala中,我會使用隱式上下文綁定來要求某些Monad[M[_]]
的可用性。我期待沒有辦法隱式地傳入模塊,但我該如何明確地做到這一點?換句話說,我可以寫的東西近似的:
let sequence (module M : Monad.S) foo =
let open M in
let open M.Monad_infix in
List.fold ~init:(return []) ~f:(fun acc x ->
acc >>= fun acc' ->
x >>= fun x' ->
return (x' :: acc')
) foo;;
這是不是可以用第一類模塊來完成?
編輯:好吧,所以它實際上並沒有發生,我嘗試使用特定的代碼,它似乎比我預期的更接近工作!似乎語法事實上是有效的,但我得到這樣的結果:
Error: This expression has type 'a M.t but an expression was expected of type 'a M.t
The type constructor M.t would escape its scope
錯誤的第一部分還是很迷惑,因爲它們匹配,所以我猜這個問題是第二個 - 是這裏的問題返回類型似乎沒有確定?我想它是依賴於傳入的模塊 - 這是一個問題嗎?有沒有辦法解決這個實現?
這個老問題可能對你有用:http://stackoverflow.com/questions/1986374/higher-order-type-constructors-and-functors-in-ocaml – rgrinberg 2013-02-26 15:10:48