众所周知,OCaml具有参数多态性,这导致了一些限制。Haskell通过它的类型类提供了一种 ad hoc 多态性,显然,这在某些情况下非常方便。同样众所周知的是,OCaml的模块和函子系统允许创建一种 ad hoc 多态性。例如,请参见Simon Shine here最近的伟大回答。
我的观点是,在Haskell中可以创建派生几个类型类的类型。例如:
data Person = Person { firstName :: String
, lastName :: String
, age :: Int
} deriving (Eq, Show, Read)
这对于定义具有多个特性的类型非常方便(在给定的示例中,允许类型Person
的值支持相等性测试、可打印和可读)。
我的问题如下:我们能在OCaml中简单地做同样的事情吗?我所说的 simply 是指使用语言的基本语法,而不需要很多技巧。
为了给予一个比较具体的例子,假设我们有两个OCaml签名
module type Showable = sig
type t
val to_string : t -> string
end
module type Readable = sig
type t
val from_string : string -> t
end
目标是写一个函子F
,它由一个实现Showable
和Readable
的模块参数化。
1条答案
按热度按时间gfttwv5a1#
当然,这实际上很简单,使用模块包含。
手册中对破坏性替代进行了说明:http://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec234
剩下的是常规的模块内容(完整的解释请参见手册)
一些函子很重的库非常依赖于这种结构化的子类型。例如,ocamlgraph中的每个函子都定义了自己的模块类型参数。这里是Kruskal module的一个例子。函子期望一个
Kruskal.G
类型的模块,它实现了Sig.G
的子签名(大多数图模块都实现了)。