在阅读各种关于函数式编程的文章时,我遇到过几次“Functor”这个术语,但作者通常认为读者已经理解了这个术语。在网络上你可以看到一些过于技术性的描述(参见维基百科的文章),也可以看到一些非常模糊的描述(参见ocaml-tutorial网站上关于函数函数的部分)。

有没有人可以定义这个术语,解释它的用法,或者提供一个如何创建和使用函子的例子?

编辑:虽然我对这个术语背后的理论很感兴趣,但我对这个概念的实现和实际应用更感兴趣,而不是理论。

编辑2:看起来好像有一些交叉术语:我特别指的是函数式编程的函子,而不是c++的函数对象。


当前回答

函数子是一个具有映射方法的对象。

JavaScript中的数组实现了map,因此是函子。承诺、流和树通常在函数式语言中实现map,当它们这样做时,它们被认为是函子。函子的map方法获取它自己的内容,并使用传递给map的转换回调对它们进行转换,并返回一个新的函子,该函子包含作为第一个函子的结构,但带有转换后的值。

src: https://www.youtube.com/watch?v=DisD9ftUyCk&feature=youtu.be&t=76

其他回答

实际上,functor是指在c++中实现调用操作符的对象。在ocaml中,我认为函子指的是将一个模块作为输入并输出另一个模块的东西。

Functor与函数式编程没有特别的关系。它只是一个指向函数或某种对象的“指针”,可以像调用函数一样调用它。

这个问题的最佳答案在布伦特·约吉(Brent Yorgey)的《type eclassopedia》中找到。

这一期的单子阅读器包含了一个精确的定义,什么是一个函子以及许多其他概念的定义以及一个图表。(Monoid, Applicative, Monad和其他概念被解释和看到与函子的关系)。

http://haskell.org/sitewiki/images/8/85/TMR-Issue13.pdf

摘自Functor的Typeclassopedia: 一个简单的直觉是,一个Functor代表一个容器 类中的每个元素统一应用函数的能力 容器”

但实际上,所有类型的类目都是强烈推荐的,因为它们出奇地简单。在某种程度上,你可以看到这里的类型类与object中的设计模式是平行的,因为它们为给定的行为或能力提供了词汇表。

干杯

函子是对象和态射的映射,它保留了一个类别的组成和身份。

让我们定义什么是类别?

是一堆东西! 在a内部画几个点(现在是两个点,一个是“a”,另一个是“b”) 圆圈,并命名为圆圈A(类别)。

这个类别包含什么?

对象之间的组合和每个对象的恒等函数。

因此,在应用Functor之后,我们必须映射对象并保存组合。

让我们想象‘A’是我们的范畴,它有对象[' A', 'b'],并且存在一个态射A -> b

现在,我们必须定义一个函子,它可以将这些对象和态射映射到另一个类别“B”。

假设这个函子叫做Maybe

data Maybe a = Nothing | Just a

B类是这样的。

请再画一个圆,但这次用“也许a”和“也许b”代替“a”和“b”。

一切看起来都很好,所有的对象都被映射了

“a”变成了“也许a”,“b”变成了“也许b”。

但问题是我们也要把态射从a映射到b。

这意味着' a'中的态态a -> b应该映射到'可能a' -> '可能b'

来自a -> b的形态称为f,然后来自'Maybe a' -> 'Maybe b'的形态称为'fmap f'

现在让我们看看函数f在A中做了什么,看看我们能否在B中复制它

A中f的函数定义:

f :: a -> b

F取a并返回b

f在B中的函数定义:

f :: Maybe a -> Maybe b

f取也许a,返回也许b

让我们看看如何使用fmap将函数'f'从'A'映射到'B'中的函数'fmap f'

fmap的定义

fmap :: (a -> b) -> (Maybe a -> Maybe b)
fmap f Nothing = Nothing
fmap f (Just x) = Just(f x)

那么,我们在这里做什么?

我们将函数“f”应用于类型为“a”的“x”。“Nothing”的特殊模式匹配来自于Functor Maybe的定义。

因此,我们将对象[a, b]和形态[f]从类别' a '映射到类别' b '。

那是富克托!

你回答了不少不错的问题。我将加入:

函子,在数学意义上,是代数上一种特殊的函数。它是将一个代数映射到另一个代数的最小函数。“极简性”用函子定律来表示。

有两种方式来看待这个问题。例如,列表是某些类型的函子。也就是说,给定类型为“a”的代数,您可以生成包含类型为“a”的列表的兼容代数。(例如:将一个元素带到包含它的单元素列表的映射:f(a) = [a])同样,兼容性的概念是由函子定律表示的。

另一方面,鉴于函子f / a型,(也就是说,f是应用函子的结果f的代数a型),从g和功能:- > b,我们可以计算一个新的函子f = (fmap g)映射f a到f b。简而言之,fmap是f的一部分映射“函子零件”“函子零件”,和g函数的一部分,“代数”映射到“代数部分”。它接受一个函数,一个函子,一旦完成,它也是一个函子。

看起来不同的语言使用不同的函子概念,但事实并非如此。它们只是在不同的代数上使用函子。OCamls有一个模块代数,这个代数上的函子允许您以一种“兼容”的方式将新声明附加到模块。

Haskell函子不是类型类。它是一个具有满足类型类的自由变量的数据类型。如果您愿意深入挖掘数据类型的精髓(没有自由变量),您可以通过底层代数将数据类型重新解释为函子。例如:

数据F = F Int

是整型类的同构。F,作为一个值构造函数,是一个将Int映射到F Int的函数,一个等价的代数。它是一个函子。另一方面,这里的fmap不是免费的。这就是模式匹配的作用。

函子很适合以一种代数相容的方式将事物“附加”到代数元素上。