每个方法都返回`this`是monad吗?

时间:2010-08-19 19:01:52

标签: oop functional-programming monads

类的每个方法都返回this一个monad吗?

4 个答案:

答案 0 :(得分:7)

我会说“可能”非常谨慎。这很大程度上取决于您的定义。

值得注意的是,我从category theory construct而不是functional programming construct采用了monad的定义。

如果您考虑类A的方法CC实例映射到另一个C实例(即它返回this),那么这似乎C.A()是一个由C实例组成的类别的仿函数。因此,它至少是一个endofunctor。看起来这种结构符合我们期望的基本身份和结合特性,但需要进一步检查才能确定。

无论如何,我不会把自己的生命放在上面,而且我不确定这对于思考这样的结构是一种非常有用的方式,但至少在第一次检查时看起来似乎是合理的假设。

答案 1 :(得分:4)

我对monad的理解有限。我不知道这是否符合monad的正式定义(我不这么认为,但我不确定),但return this;单独不允许monad允许的任何酷事(流体接口很好,但不是monad imho,甚至像选项类型monad这样简单的monad也没用。)

维基百科的这个片段似乎说“不”:

  

正式地,monad是由定义两个操作(绑定和返回)和类型构造函数M构建的[...这里我们不需要进一步的限制]

编辑:此外,monad是一个类型而不是一个操作(例如方法) - 问题应该是“如果一个类是一个monad,如果它的所有方法都返回this?”< / nitpick&gt ;

答案 2 :(得分:4)

可能不是,至少不是以任何通常的方式。

编程中的Monad通常在一类类型上定义,其功能为箭头。在这种情况下,返回this的方法是从类到自身的箭头 - 这是一个endo morphism ,具有通常的函数组合,但不是仿函数

请注意,涉及函数类型的仿函数当然是可能的,但仿函数F(A) => (A -> A)并不真正起作用,因为类型出现在协变和逆变位置,也就是说,给定函数A -> B你可以将A -> A发送至A -> B,或者您可以将B -> B发送至A -> B,但无法从B -> B获得A -> A,反之亦然


但是,有一种方法可以将实例视为具有monadic结构。考虑实例方法有效地将this作为隐式参数。所以对于某些C类,它的方法是从C到其他任何类型的函数。这大致对应于上面的协变函数函子。请注意,我不是在这里描述任何特定的,而是描述类和实例的整个概念!因此,对于从C到C的实例方法的映射:

  • 如果我们有一个返回某个类型A的实例方法和一个类型为A -> B的函数,我们可以简单地定义一个返回B类型的方法:其余的就是其余的仿函数定义,又名Haskell中的'fmap`。

  • 如果我们有一些A类型的值,我们可以添加一个简单的实例方法,只返回该值:这是monad的“单元”操作,在Haskell中是a.k.a。return

  • 如果我们有一个实例方法返回类型为A的值,另一个实例方法使用类型为A的参数并返回类型为B的值,那么我们可以通过组合它们来定义一个简单地返回类型B的值的方法。这就是哈萨克尔的monadic bind,a.k.a。(>>=)

Haskell调用monad的“函数,它们都采用某种固定类型的第一个参数”读者Monad,并且do符号可以让你编写代码,其中第一个参数是隐式可用的 - 而不是像实例方法中this隐式可用的方式。

这里的区别在于,对于类实例,monadic结构是......在语法的层次上,而不是你可以在程序中直接使用的东西,至少在大多数情况下都不是语言。

答案 3 :(得分:1)

在我看来,没有。

我看到至少有两个问题。

  1. monad通常是两个函数之间的粘合剂。在这种情况下, methodA 返回一个类型,在该类型上调用下一个 methodB (当然还有 methodA methodB 属于同一类型)。
  2. monad应该允许类型转换。因此,如果 functionA 返回 TypeX functionB 需要 TypeY ,则monad需要提供一个可以转换为 Monad(TypeX)进入 Monad(TypeY)。然后monad继续获取第一个函数的返回值,将其包装为 Monad(TypeX),将其转换为 Monad(TypeY),其中将提取TypeY 并将其输入 functionB
  3. 返回此方法实际上是Fluent Interface的一个实现。尽管许多人认为它也是一个monadic,但我只会说,虽然它有助于解决类似于monads可以解决的问题,而解决方案看起来类似于monadic解决方案可能如何工作(而不是“ 。“运算符,monad的bind方法必须在没有任何显式do块的情况下调用),它不是monad。换句话说,它可能像monad一样走路,像monad一样说话,但它不是monad。

    对第2点的轻微修正:monad需要提供机制来a)将TypeX转换为Monad(TypeX),从Monad(TypeX)转换为Monad(TypeY)以及从Monad转换( TypeY)到TypeY