Haskell和OCaml中的函子有什么相似之处?

Haskell和OCaml中的函子有什么相似之处?,haskell,ocaml,Haskell,Ocaml,在过去一年左右的时间里,我一直在哈斯克尔家玩,实际上我已经开始“了解”它,直到单子、镜头、字体系列。。。很多 我将要离开这个舒适区一点,我将搬到一个OCaml项目作为一份日常工作。稍微浏览一下语法,我在寻找类似的更高级概念,比如函子 我阅读了OCaml中的代码和函子的结构,但我似乎不知道它们在Haskell和OCaml中是否是类似的概念。 简而言之,Haskell中的函子对我来说主要是一种提升Haskell中函数的方法,我就是这样使用它的。 在OCaml中,它让我感觉它更接近于编程接口(例如,当

在过去一年左右的时间里,我一直在哈斯克尔家玩,实际上我已经开始“了解”它,直到单子、镜头、字体系列。。。很多

我将要离开这个舒适区一点,我将搬到一个OCaml项目作为一份日常工作。稍微浏览一下语法,我在寻找类似的更高级概念,比如函子

我阅读了OCaml中的代码和函子的结构,但我似乎不知道它们在Haskell和OCaml中是否是类似的概念。 简而言之,Haskell中的函子对我来说主要是一种提升Haskell中函数的方法,我就是这样使用它的。 在OCaml中,它让我感觉它更接近于编程接口(例如,当使用比较函数生成集合或列表时),我真的不知道如何将函数提升到函子上

有人能给我解释一下这两个概念是否相似,如果相似,我遗漏了什么或没有看到什么?我在谷歌上搜索了一下,似乎没有找到明确的答案


Kasper

从实用的角度来看,您可以认为OCaml和Haskell中的“函子”是不相关的。正如您所说,在Haskell中,函子是允许您在其上映射函数的任何类型。在OCaml中,函子是由另一个模块参数化的模块

很好地描述了两种语言中的函子是什么以及它们之间的区别

然而,顾名思义,这两个看似不同的概念之间实际上存在着联系!这两种语言的函子都只是范畴论中一个概念的实现

范畴理论是对范畴的研究,范畴只是对象的任意集合,它们之间有“态射”。范畴的概念是非常抽象的,因此“对象”和“态射”实际上可以是任何东西,只要有一些限制,每个对象都必须有一个同一态射,态射必须组合

一个类别最明显的例子是集合和函数的类别:集合是对象,集合之间的函数是态射。显然,每个集合都有一个标识函数,并且可以组合函数。通过查看Haskell或OCaml之类的函数式编程语言,可以形成一个非常类似的类别:具体类型(例如,带有kind
*
的类型)是对象,Haskell/OCaml函数是它们之间的变形

在范畴论中,函子是范畴之间的变换。它就像一个类别之间的函数。当我们研究Haskell类型的类别时,函子本质上是一个类型级函数:它将类型映射到其他类型。我们关心的特殊类型的函子将类型映射到其他类型。一个完美的例子是
Maybe
Maybe
Int
映射到
Maybe Int
String
映射到
Maybe String
等等。它为每个可能的Haskell类型提供映射

函子还有一个额外的要求,它们必须映射类别的态射以及对象。特别是,如果我们有一个态射
a→ B
和我们的函子将
A
映射到
A'
B
映射到
B'
,它必须映射态射
A→ B
到某个态射
A'→ B'
。作为一个具体的例子,假设我们有类型
Int
String
。有一大堆Haskell函数
Int→ 字符串
。要使
Maybe
成为一个合适的函子,它必须有一个函数
Maybe Int→ 可能是字符串

幸运的是,这正是
fmap
函数所映射的函数。对于
可能
,其类型为
(a→ (b)→ 也许是→ 也许是b
;我们可以添加一些括号来获得:
(a→ (b)→ (也许是→ 也许b)
。这个类型签名告诉我们的是,对于我们拥有的任何普通函数,我们在
可能
s上也有一个对应的函数

所以函子是类型之间的映射,也保留了它们之间的函数。
fmap
函数本质上只是对函子的第二个限制的证明。这使得我们很容易看到Haskell
函子
类只是数学概念的一个特定版本

那么OCaml呢?在OCaml中,函子不是类型,而是模块。特别是,它是一个参数化模块:一个将另一个模块作为参数的模块。我们已经看到了一些相似之处:在Haskell中,
函子类似于类型级函数;在OCaml中,函子类似于模块级函数。所以实际上,这是同样的数学概念;但是,它不是用于Haskell中的类型,而是用于模块

关于OCaml函子如何与CS站点上的范畴论函子相关,有更多的细节:。这个问题讨论的是SML而不是OCaml本身,但我的理解是OCaml的模块系统与SML的模块系统密切相关

总之:Haskell和OCaml中的函子是两种根本不同的结构,它们恰好是同一个非常抽象的数学概念的具体化。我认为它非常简洁:)。

坦白地说,(1)我不确定对范畴理论的喋喋不休实际上有助于大多数初学者理解什么是Haskell函子。它可能应该保留给更高级的语言设计研究。(2) ML函子和范畴理论之间的关系简直是胡说八道。这是对某些东西的复古解释,可能只是选择了一个看起来像“function”的名称,对于使用ML函子来说不是特别有说服力,也没有帮助。你可以说“模块之间的函数”,省去了每个人的麻烦。@gasche:(1)对我来说,函子只有在我读到它们背后的范畴理论时才真正有意义。T