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

时间:2013-05-03 06:37:13

标签: haskell ocaml

在过去的一年左右的时间里,我一直在玩Haskell,我实际上已经开始'得到'它,直到Monads,Lenses,Type Families,......很多。

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

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

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

卡斯帕

1 个答案:

答案 0 :(得分:45)

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

In Functional Programming, what is a functor?很好地描述了两种语言中的仿函数以及它们的区别

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

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

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

在类别理论中,仿函数是类别之间的转换。它就像是类别之间的功能。当我们查看Haskell类型的类别时,仿函数本质上是一个类型级函数:它将类型映射到其他类型。我们关心的特殊类型的仿函数将类型映射到其他类型。一个完美的例子是MaybeMaybe地图IntMaybe IntStringMaybe String等等。它为每个可能的Haskell类型提供了映射。

Functors有一个额外的要求 - 他们必须映射类别的态射以及对象。特别是,如果我们有一个态射A → B而我们的函子将A映射到A'BB',它必须映射态射{{1一些态射A → B。举一个具体的例子,假设我们有类型A' → B'Int。有一大堆Haskell函数String。要使Int → String成为一个合适的函子,它必须为每个函数都有一个函数Maybe

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

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

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

关于CSaml仿函数如何与CS网站上的类别理论仿函数相关的更多细节:What is the relation between functors in SML and Category theory?。这个问题讨论的是SML而不是OCaml 本身,但我的理解是OCaml的模块系统与SML的模块系统密切相关。

总结:Haskell和OCaml中的仿函数是两个根本不同的结构,它们恰好是对同一个非常抽象的数学概念的回应。我觉得它非常整洁:)。