简体   繁体   English

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

[英]OCaml functors, Haskell type classes, and multiple derivation

It is well-known that OCaml has a parametric polymorphism and this leads to some limitations. 众所周知,OCaml具有参数多态性,这导致一些限制。 Haskell, through its type classes, offers an ad hoc polymorphism, which is, obviously, very convenient in several situations. Haskell通过它的类型类提供了一种特殊的多态性,在很多情况下显然非常方便。 It is also well-known that the system of modules and functors of OCaml allows to create a kind of ad hoc polymorphism. 众所周知,OCaml的模块和仿函数系统允许创建一种特殊的多态性。 See the great recent answer of Simon Shine here for instance. 看人妖的伟大最近的答案闪耀这里的实例。

My point is that it is possible in Haskell to create types that derive several types classes . 我的观点是,在Haskell中可以创建派生多个类型类的类型 For instance : 例如 :

data Person = Person { firstName :: String
                 , lastName :: String
                 , age :: Int
                 } deriving (Eq, Show, Read)

This is very convenient to define types having several features (allowing values of type Person to support equality tests, be printable, and be readable in the given example). 定义具有多个功能的类型非常方便(允许Person类型的值支持相等性测试,可打印,并且在给定示例中可读)。

My question is the following: Can we do the same, simply, in OCaml? 我的问题如下:我们可以在OCaml中做同样的事吗? By simply I mean with the ground syntax of the language and without many artifices. 简单地说,我的意思是语言的基础语法,没有很多人工制品。

To give a somewhat concrete example, suppose we have two OCaml signatures 举一个具体的例子,假设我们有两个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

The aim is to write a functor F parametrized by a module which implements both Showable and Readable . 目的是编写一个由一个实现ShowableReadable的模块参数化的Showable函数F

Sure, that's actually quite easy, use module inclusion. 当然,这实际上非常简单,使用模块包含。

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

Destructive substitution is explained in the manual: http://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec234 手册中解释了破坏性替换: http//caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec234
The rest is regular module stuff (see the manual for a complete explanation) 其余的是常规模块内容(有关完整说明,请参阅手册)

Some functor-heavy library rely on this kind of structural subtyping quite a lot. 一些算函重型库非常依赖于这种结构子类型。 For example, each functor in ocamlgraph define its own module type argument. 例如, ocamlgraph中的每个仿函数定义了自己的模块类型参数。 Here is an example with the Kruskal module . 以下是Kruskal模块的示例。 The functor expect a module of type Kruskal.G , which implements a subsignature of Sig.G (which is implemented by most graph modules). Kruskal.G函数期望一个Kruskal.G类型的模块,它实现了Sig.G的子Sig.G (由大多数图形模块实现)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM