OCaml自定义Monad编译失败:Try.Success未绑定构造器求助
问题原因
你遇到的错误是因为模块签名TRY只对外暴露了抽象类型'a t和return函数,没有公开Success和Failure这两个构造器。当你给Try模块加上: TRY的签名约束后,外部代码只能看到签名里定义的内容,构造器被隐藏了,所以编译器找不到Try.Success和Try.Failure。
解决方案
根据你的需求,有两种常见的解决方式:
方式1:在签名中公开构造器
如果你希望外部代码可以直接匹配Success和Failure,修改TRY签名,把类型的具体构造器暴露出来:
module type TRY = sig type 'a t = Success of 'a | Failure of exn val return : 'a -> 'a t end module Try : TRY = struct type 'a t = Success of 'a | Failure of exn let return a = Success a end let () = match Try.return 5 with | Try.Success a -> print_int a | Try.Failure e -> print_endline (Printexc.to_string e)
这样编译就能通过,因为构造器已经被签名公开,外部代码可以直接访问。
方式2:保持类型抽象,提供辅助访问函数
如果想保持'a t的抽象性(隐藏内部实现细节,这是Monad常见的封装方式),可以在签名中添加辅助函数,让外部代码不用直接接触构造器:
module type TRY = sig type 'a t val return : 'a -> 'a t val fold : 'a t -> success:('a -> unit) -> failure:(exn -> unit) -> unit end module Try : TRY = struct type 'a t = Success of 'a | Failure of exn let return a = Success a let fold t ~success ~failure = match t with | Success a -> success a | Failure e -> failure e end let () = Try.fold (Try.return 5) ~success:(fun a -> print_int a) ~failure:(fun e -> print_endline (Printexc.to_string e))
这种方式更符合Monad的封装原则,外部只需要通过提供的函数操作'a t类型的值,不用关心内部是用什么构造器实现的。
内容的提问来源于stack exchange,提问作者Jaja
相关产品推荐
相关产品推荐

