通俗解释什么函数编程中的函子Functors? - iRi


什么是函子?
事实:如果您有Blob的来源,以及可以将Blob转换为Thing的函数,则可以将它们放在一起以创建Things的来源。
例子:

  • 如果我有 A(一个整数列表)和 B(一个将整数转换为字符串的函数),我可以轻松创建 C(一个字符串列表)。
  • 如果我有 A(一个整数到字符串的哈希表),和 B(一个将字符串转换为布尔值的函数),我可以有 C(一个整数到布尔值的哈希表)。

那什么是函子Functor 呢?函子Functor 是一个接口(或“特征”、“概念”、“类型类”或任何您的语言喜欢的东西;从现在开始使用“接口”,因为我有意尝试使用更常用的术语),它允许您将上述事实称为一流的语言元素。在 Haskell 的案例中,Functor是通过提供fmap实现来实现的。对于上述示例,函数将:
  • 列表实现:获取 B 中的函数并在我的所有元素上运行它并返回一个新列表,通常称为map。
  • 哈希表实现:取B中的函数对我所有的值运行它,返回一个具有相同键和新值的新哈希表。
  • 函数实现:返回一个在A中运行函数的函数,然后在结果上运行B中的函数。这通常称为函数组合。

最后一个有点棘手,但是如果您将其比喻中的函数视为在左侧接受输入并在右侧提供输出的黑匣子,那就是将第二个函数猛烈撞击第一个函数的右侧创建一个新的。这就是为什么我说某物的“来源”;这里的原则非常通用,并且超越了函数、容器和我拥有的所有其他方便的词……它适用于您可能从中获取值的任何事物
 
“函子”不是名词
出于他们自己的充分理由,数学家使用“函子”作为具体名词。Haskell 复制了这个,因此你经常听到“一个函子”。
然而,接口是描述数据结构的形容词,这就是为什么在许多语言中它们通常以-able后缀(Iterable、Serializable 等)命名。程序员最好将其视为 Functable 或 Fmapable 或类似的东西。
 
“函子”并不总是容器
函子可以应用于许多不是容器的东西。我们已经在函数中看到了这一点。在非 Haskell 实现中,假设函子实现只能在容器上运行是一个常见的错误。

关于什么是单子Monads点击标题见原文。
函子是我们可以随意找到的自然事物。Monad 实现通常需要我们实际上经过深思熟虑来构建以适应抽象。