OCaml仿函数,Haskell类型类和多个派生

时间:2016-06-13 21:16:36

标签: haskell functional-programming ocaml functor caml

众所周知,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中做同样的事吗?通过简单地我的意思是语言的基础语法,没有很多技巧。

举一个具体的例子,假设我们有两个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

目的是编写一个由FShowable实现的模块参数化的仿函数Readable

1 个答案:

答案 0 :(得分:12)

当然,这实际上非常简单,请使用模块包含。

module type S = sig
  include Showable
  include Readable with type t := t (* destructive substitution *)
end

module F ( M : S ) = struct
  let fake_id x = M.from_string @@ M.to_string x
end

手册中解释了破坏性替代:http://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec234
其余的是常规模块内容(有关完整说明,请参阅手册)

一些算函重型库非常依赖于这种结构子类型。例如,ocamlgraph中的每个仿函数都定义了自己的模块类型参数。以下是Kruskal module的示例。仿函数期望一个Kruskal.G类型的模块,它实现Sig.G的子签名(由大多数图形模块实现)。

相关问题