我在阅读有关函数式编程的各种文章时多次遇到“函子”一词,但作者通常假设读者已经理解该术语。在网络上环顾四周,要么提供了过多的技术描述(请参阅维基百科文章)或令人难以置信的模糊描述(请参阅此处有关函子的部分ocaml-教程网站).
有人可以定义这个术语,解释它的用途,或者提供一个如何创建和使用函子的示例吗?
Edit:虽然我对这个术语背后的理论感兴趣,但我对这个概念的实施和实际使用的兴趣不如对理论的兴趣。
Edit 2:看起来好像存在一些跨术语:我特指的是函数式编程的函子,而不是 C++ 的函数对象。
“函子”这个词来自范畴论,范畴论是一个非常普遍、非常抽象的数学分支。函数式语言的设计者至少以两种不同的方式借用了它。
-
在 ML 语言系列中,函子是一种采用一个或多个其他模块作为参数的模块。它被认为是一项高级功能,大多数初学者都很难使用它。
作为实现和实际使用的示例,您可以将您最喜欢的平衡二叉搜索树形式一劳永逸地定义为函子,并且它将采用提供以下功能的模块作为参数:
一旦完成此操作,您就可以永远使用相同的平衡二叉树实现。 (存储在树中的值的类型通常是多态的——树除了复制它们之外不需要查看值,而树肯定需要能够比较键,并且它从函子的参数。)
ML 函子的另一个应用是分层网络协议。该链接是 CMU Fox 小组发表的一篇非常棒的论文;它展示了如何使用仿函数在较简单的层类型(如 IP 甚至直接通过以太网)上构建更复杂的协议层(如 TCP)。每一层都被实现为一个函子,将其下面的层作为参数。软件的结构实际上反映了人们思考问题的方式,而不是只存在于程序员头脑中的层次。 1994年这部作品出版时,轰动一时。
有关 ML 函子的实际应用示例,您可以参阅论文机器学习模块狂热,其中包含一个可发布的(即可怕的)函子工作示例。要对 ML 模块系统进行精彩、清晰、清晰的解释(以及与其他类型的模块的比较),请阅读 Xavier Leroy 1994 年发表的精彩 POPL 论文的前几页清单类型、模块和单独编译.
-
在 Haskell 和一些相关的纯函数式语言中,Functor
is a 类型类别。当类型提供具有某些预期行为的某些操作时,该类型属于某个类型类(或者更技术地说,该类型“是该类型类的实例”)。一种T
可以属于班级Functor
如果它具有某些类似集合的行为:
-
方式T
通过另一种类型进行参数化,您应该将其视为集合的元素类型。完整集合的类型类似于T Int
, T String
, T Bool
,如果您分别包含整数、字符串或布尔值。如果元素类型未知,则将其写为类型参数 a
, as in T a
.
示例包括列表(零个或多个类型的元素a
), the Maybe
type(类型的零个或一个元素a
),类型元素的集合a
, 类型元素数组a
,包含类型值的各种搜索树a
,以及您能想到的许多其他内容。
-
另一个财产是T
必须满足的是,如果你有一个类型的函数a -> b
(元素上的函数),那么您必须能够采用该函数并在集合上产生相关的函数。您与操作员一起执行此操作fmap
,这是由每个类型共享的Functor
类型类。该运算符实际上是重载的,所以如果你有一个函数even
与类型Int -> Bool
, then
fmap even
是一个重载函数,可以做很多奇妙的事情:
在 Haskell 中,该属性通过给出以下类型来表示:fmap
:
fmap :: (Functor t) => (a -> b) -> t a -> t b
我们现在有一个小的t
,这意味着“任何类型Functor
class."
长话短说,在 Haskell 中函子是一种集合,如果给它一个元素上的函数,fmap
会给你一个关于集合的函数。正如你可以想象的,这是一个可以广泛重用的想法,这就是为什么它被祝福成为 Haskell 标准库的一部分。
像往常一样,人们不断发明新的、有用的抽象,你可能想研究一下应用性的函子,最好的参考可能是一篇名为带有效果的应用程序编程作者:康纳·麦克布莱德和罗斯·帕特森。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)