假设我有一个选项列表:
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
. 核心似乎使用函子来提供更高种类的类型的效果,但我不清楚如何编写要在模块上抽象的函数。在 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
错误的第一部分似乎令人困惑,因为它们匹配,所以我猜问题出在第二部分 - 这里的问题是返回类型似乎没有确定吗?我想它取决于传入的模块 - 这是一个问题吗?有没有办法修复这个实现?