OCaml函子、Haskell类型类和多重派生
众所周知,OCaml具有参数多态性,这导致了一些限制。Haskell通过其类型类提供了一种特殊的多态性,显然,这种多态性在几种情况下非常方便。众所周知,OCaml的模块和函子系统允许创建一种特殊的多态性。例如,请参阅Simon Shine最近的精彩回答 我的观点是,在Haskell中可以创建派生多个类型类的类型。例如:OCaml函子、Haskell类型类和多重派生,haskell,functional-programming,ocaml,functor,caml,Haskell,Functional Programming,Ocaml,Functor,Caml,众所周知,OCaml具有参数多态性,这导致了一些限制。Haskell通过其类型类提供了一种特殊的多态性,显然,这种多态性在几种情况下非常方便。众所周知,OCaml的模块和函子系统允许创建一种特殊的多态性。例如,请参阅Simon Shine最近的精彩回答 我的观点是,在Haskell中可以创建派生多个类型类的类型。例如: data Person = Person { firstName :: String , lastName :: String
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
目标是编写一个由模块参数化的函子
F
,该模块实现了Showable
和Readable
当然,使用模块包含实际上非常简单
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
手册中解释了破坏性替换:其余部分是常规模块材料(完整解释请参见手册)
一些函子重库非常依赖这种结构子类型。例如,中的每个函子都定义自己的模块类型参数。下面是一个使用的示例。函子需要类型为
Kruskal.G
的模块,该模块实现了Sig.G
的子签名(大多数图形模块都实现了该子签名) 这一定是我见过的最好的书面问题之一!希望有人能找到答案!谢谢,这其实很简单!在某种意义上,我们可以说Haskell的类型类系统与OCaml的模和函子的类型类系统是等价的吗?它们不是等价的。如中所述,ML的模块系统比Haskell的类型类更加灵活和通用,但不允许递归。将它们结合起来意味着您不必手动编写函子应用程序,但也可以避免Haskell的问题,即每个类型只导入一个类型类实例。参见Stefan Wehr的第107-110页,了解差异的摘要。更正:比我指出的更聪明的人;Oleg Kiselyov证明了两者之间的等价性(给出了Haskell类型类的一些过时定义),尽管我找不到这篇文章,但现代Haskell类型类比ML模块更强大,因为它们提供类型级函数。我将避免做出任何更大胆的声明,并将继续编写很酷的代码片段。;-)这里:由Oleg Kiselyov和钟杰山创作。谢谢,非常有趣!