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

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

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

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


当前回答

不是为了与前面的理论或数学答案相矛盾,但Functor也是一个对象(在面向对象编程语言中),它只有一个方法,并且可以有效地用作函数。

Java中的Runnable接口就是一个例子,它只有一个方法:run。

考虑这个例子,首先在Javascript中,它有一级函数:

[1, 2, 5, 10].map(function(x) { return x*x; });

输出: [1,4,25,100]

map方法接受一个函数并返回一个新数组,其中每个元素都是将该函数应用于原始数组中相同位置的值的结果。

要在Java中使用Functor做同样的事情,你首先需要定义一个接口,比如:

public interface IntMapFunction {
  public int f(int x);
}

然后,如果你添加一个集合类,它有一个映射函数,你可以这样做:

myCollection.map(new IntMapFunction() { public int f(int x) { return x * x; } });

这使用了IntMapFunction的一个内嵌子类来创建一个Functor,它是前面JavaScript示例中的函数的OO等效。

使用函子可以在OO语言中应用函数式技术。当然,一些OO语言也直接支持函数,所以这不是必需的。

参考:http://en.wikipedia.org/wiki/Function_object

其他回答

简单地说,函子或函数对象是可以像函数一样调用的类对象。

在c++中:

这就是写函数的方法

void foo()
{
    cout << "Hello, world! I'm a function!";
}

这就是写函子的方法

class FunctorClass
{
    public:
    void operator ()
    {
        cout << "Hello, world! I'm a functor!";
    }
};

现在你可以这样做:

foo(); //result: Hello, World! I'm a function!

FunctorClass bar;
bar(); //result: Hello, World! I'm a functor!

这样做的好处是可以将state保存在类中——想象一下,如果您想询问一个函数被调用了多少次。没有办法以简洁、封装的方式做到这一点。对于函数对象,它就像任何其他类一样:你有一些实例变量,你在operator()中增加它,还有一些方法来检查这个变量,一切都很整齐。

不是为了与前面的理论或数学答案相矛盾,但Functor也是一个对象(在面向对象编程语言中),它只有一个方法,并且可以有效地用作函数。

Java中的Runnable接口就是一个例子,它只有一个方法:run。

考虑这个例子,首先在Javascript中,它有一级函数:

[1, 2, 5, 10].map(function(x) { return x*x; });

输出: [1,4,25,100]

map方法接受一个函数并返回一个新数组,其中每个元素都是将该函数应用于原始数组中相同位置的值的结果。

要在Java中使用Functor做同样的事情,你首先需要定义一个接口,比如:

public interface IntMapFunction {
  public int f(int x);
}

然后,如果你添加一个集合类,它有一个映射函数,你可以这样做:

myCollection.map(new IntMapFunction() { public int f(int x) { return x * x; } });

这使用了IntMapFunction的一个内嵌子类来创建一个Functor,它是前面JavaScript示例中的函数的OO等效。

使用函子可以在OO语言中应用函数式技术。当然,一些OO语言也直接支持函数,所以这不是必需的。

参考:http://en.wikipedia.org/wiki/Function_object

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

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

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

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

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

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

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

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

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

干杯