Functor和Monad之间有什么区别?

时间:2017-07-22 09:03:57

标签: functional-programming monads functor

这里也有类似的问题,但它们与特定的编程语言相关联,我正在寻找概念层面的答案。

据我所知,Functors本质上是不可变容器,它们公开了 map() API,它衍生出另一个仿函数。哪个添加可以将特定的仿函数称为monad?

据我所知,每个monad都是一个仿函数,但不是每个仿函数都是monad。

2 个答案:

答案 0 :(得分:4)

(请注意,这将是类别理论概念的简化说明)

函子

Functor是一组值a到另一组值的函数:a -> b。对于编程语言,这可以是来自String -> Integer

的函数

function fn(text: string) : integer

组合物

组合是指您使用一个函数的值作为下一个值fa(fb(x))的值的输入。例如:

hash(lowercase(text))

单子

Monad允许编写其他不可组合的Functors,通过在合成中添加额外的功能来组合Functors,或者两者兼而有之。

  • 第一个例子是玩家的Monad String -> (String, Integer)

  • 第二个例子是Monad,它计算值上调用的函数数量

Monad包含一个Functor T,它负责您想要的功能以及另外两个功能:

  • input -> T(input)
  • T(T(input)) -> T(input)

第一个函数允许将输入值转换为Monad可以组合的一组值。第二个功能允许合成。

总而言之,每个Monad都不是Functor,而是使用Functor来完成它的目的。

答案 1 :(得分:0)

让我不用进入类别理论就能解释我的理解

Functor和monad都提供一些工具来包装输入并返回包装输出。

Functor =单位+地图(工具)

在哪里, unit =它需要原始输入并将其包装在较小的上下文中。

map =它是一种将函数作为输入,将其应用于包装器中的原始值并返回包装结果的工具。

示例:让我们定义一个将整数加倍的函数 // doubleMe :: Int a-> Int b const doubleMe = a => 2 * a; Maybe(2).map(doubleMe)// Maybe(4)

Monad = unit + flatMap(或绑定或链接)

flatMap =当名称溢出时,它是使地图变平的工具。下面的示例很快就会清楚。

示例:假设我们有一个curried函数,仅当两个字符串都不为空时才追加两个字符串。

让我定义一个如下,
append ::(字符串a,字符串b)->也许是(字符串c)

现在让我们看看map(Functor附带的工具)的问题,

Maybe(“ a”)。map(append(“ b”))// Maybe(Maybe(“ ab”))

两个人怎么可能在这里?

好吧,这就是map的作用,它将提供的函数应用于包装的值并包装结果。

让我们分步进行吧

步骤1:将映射函数应用于包装后的值 此处映射的函数为append(“ b”),包装的值为“ a”,结果为Maybe(“ ab”)

步骤2:包装返回Maybe(Maybe(“ ab”))的结果。

现在我们感兴趣的值被包装两次。这里是flatMap来进行救援。 Maybe(“ a”)。flatMap(append(“ b”))// Maybe(“ ab”)

当然,函子和monad也必须遵守其他一些法律,但我认为这不在要求的范围之内。