Haskell和OCaml中的算子如何相似?

Kas*_*per 41 ocaml haskell

在过去的一年左右的时间里,我一直在哈斯克尔身边玩耍,我实际上已经开始'得到'它,直到Monads,Lenses,Type Families,......很多.

我即将离开这个舒适区,我正在转向OCaml项目作为日常工作.稍微研究一下语法,我正在寻找类似的更高级别的概念,例如functor.

我阅读了OCaml中的代码和仿函数的结构,但我似乎无法知道它们现在是否是Haskell和OCaml中的类似概念.简而言之,Haskell中的仿函数对我来说主要是一种在Haskell中提升函数的方法,我就是这样使用它(并且喜欢它).在OCaml中,它给我一种感觉,它更接近于编程到界面(例如,当使用比较函数创建一个集合或列表时),我真的不知道如何提升函数而不是仿函数.

有人可以解释我这两个概念是否相似,如果是这样,我错过了什么或没有看到什么?我用Google搜索了一下,似乎找不到明确的答案.

卡斯帕

Tik*_*vis 45

从实际的角度来看,你可以将OCaml和Haskell中的"函子"视为无关.正如你所说,在Haskell中,仿函数是允许你在其上映射函数的任何类型.在OCaml中,仿函数是由另一个模块参数化的模块.

在函数式编程中,什么是函子?很好地描述了两种语言中的仿函数以及它们的区别.

然而,顾名思义,两个看似不同的概念实际上存在联系!两种语言的仿函数都只是来自类别理论的概念的实现.

范畴理论是对范畴的研究,它们只是在它们之间具有"态射"的对象的任意集合.类别的概念是非常抽象的,因此"对象"和"态射"实际上可以是具有一些限制的任何东西 - 必须存在每个对象的身份态射,并且态射必须构成.

类别中最明显的例子是集合和函数的类别:集合是对象,而函数之间的集合是态射.显然,每一组都有一个身份功能,并且可以组成功能.通过查看像Haskell或OCaml这样的函数式编程语言可以形成一个非常相似的类:具体类型(例如类型的类型*)是对象,Haskell/OCaml函数是它们之间的态射.

在类别理论中,仿函数是类别之间的转换.它就像是类别之间的功能.当我们查看Haskell类型的类别时,仿函数本质上是一个类型级函数:它将类型映射到其他类型.我们关心的特殊类型的仿函数将类型映射到其他类型.这方面的一个很好的例子是Maybe:Maybe地图IntMaybe Int,StringMaybe String等.它为每种可能的Haskell类型提供映射.

函子有一个额外的要求 - 他们必须映射类别的态射以及对象.特别是,如果我们有一个射A ? B和我们的仿函数映射AA'BB',它必须映射射A ? B一些同态A' ? B'.举一个具体的例子,假设我们有类型IntString.有一大堆Haskell函数Int ? String.为了Maybe成为一个合适的函子,它必须具备Maybe Int ? Maybe String每个函数的功能.

令人高兴的是,这正是fmap函数所做的 - 它映射函数.因为Maybe它有类型(a ? b) ? Maybe a ? Maybe b; 我们可以添加一些括号来获得:(a ? b) ? (Maybe a ? Maybe b).这种类型的签名告诉我们的是,对于我们拥有的任何正常函数,我们在Maybes上也有相应的函数.

因此,仿函数是类型之间的映射,它也保留了它们之间的函数.该fmap函数基本上只是对仿函数的第二个限制的证明.这使得很容易看出Haskell Functor类是如何只是数学概念的特定版本.

那么OCaml呢?在OCaml中,仿函数不是类型 - 它是一个模块.特别是,它是一个参数化模块:一个以另一个模块作为参数的模块.我们已经可以看到一些相似之处:在Haskell中,a Functor类似于类型级函数; 在OCaml中,仿函数就像一个模块级函数.真的,这是相同的数学思想; 然而,不是在Haskell中使用类型 - 而是在模块上使用它.

关于CSaml仿函数如何与CS网站上的类别理论仿函数相关的更多细节:SML中的仿函数与类别理论之间的关系是什么?.这个问题谈论的是SML而不是OCaml 本身,但我的理解是OCaml的模块系统与SML的模块系统密切相关.

总结:Haskell和OCaml中的函子是两个根本不同的结构,它们恰好是对同一个非常抽象的数学概念的反应.我觉得它很漂亮:).

  • @gasche:(1)对我而言,当我读到它们背后的范畴理论时,仿函数才真正有意义.在那之前他们似乎很随意.有一些很好的教程将所有内容都放在透视图中,但遗憾的是我丢失了链接.我真的希望我早些时候找到了这个教程.(2)我不太了解ML的设计方式,但似乎很合适.重要的是要看到Haskell想法和ML想法之间的相似之处. (11认同)
  • 坦率地说,(1)我不确定关于类别理论的喋喋不休实际上有助于大多数初学者理解Haskell仿函数是什么.它应该保留给语言设计的更高级的查询.(2)ML仿函数和类别理论之间的关系几乎是胡说八道.这是一个复古的解释,可能只是选择了一个看起来像"功能"的名称,并且对于使用ML仿函数并不是特别有说服力也没有帮助.您可以说"模块之间的功能"并为每个人节省麻烦. (8认同)
  • 我发现这个答案非常有趣. (5认同)
  • 我也认为类别理论确实不合适.关于'fmap',我还在讨论模块对模块函子的影响.我会看看是否有新的问题;-) (2认同)