我对OCaml中的抽象类型有疑问 .
假设我有一个隐藏某种类型的模块:
module Test : sig
type t
val make_t : unit -> t
end = struct
type t = int option
let make_t () = Some 42
end
而且我还有一个对选项进行操作的函数:
let do_work : 'a option -> unit = function
| Some x -> Printf.printf "Some\n"
| None -> Printf.printf "None\n"
毫不奇怪,当我在t实例上调用do_work时出现类型错误:
let () =
do_work @@ Test.make_t ()
错误:此表达式的类型为Test.t,但表达式的类型为'a option
在我的应用程序中,我比int选项更复杂,我不想向外暴露它的内部 . 但是,我想告诉OCaml编译器t实际上是一个选项 . 我怎样才能做到这一点?
5 回答
或者您可以提供抽象以允许正确类型的函数应用
操作员可能有点太多但看起来更酷 . 另外,您可能需要查看monad .
最直接的方法是只使选项的内容类型为abstract:
如果您不想公开您的实现,但是您需要使类型与其他类型兼容,请编写函数以转换为这些类型/从这些类型转换:
然后,当你特别需要
int option
时:这样,您的类型
Test.t
保持抽象,这意味着您可以在不更改接口的情况下更改实现,前提是您在转换器中执行必要操作以保持其一致性 .看来你想要的是使
t
成为私人类型:与抽象类型解决方案一样,它允许对
t
的实例的创建进行一些控制,但允许解构此类实例(封装可防止) .除了这里已有的好答案,如果您只关心某些东西是
Some _
还是None
,您可以将其添加到您的界面:(当然你可以将
is_some
重命名为与你的抽象相匹配的东西)