比方说,我有一个选项列表: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