最近,我一直在整理关于Monads工作原理的知识。还向我介绍了'Comonad'的概念,它被描述为monad 的逆对偶。但是,我不可能把头缠住它。
为了了解Monad,我为自己做了一个比喻:
Monads可以看作是“构建表达传送带的蓝图”。
要定义一个新的Monad(一种新型的传送带系统),您需要定义:
- 一种在传送带上放置东西的方法,例如“启动”传送带。(称为
unit
或return
)- 将作为传送带一部分的机器(表达式)连接到传送带的一种方式。(称为
join
或bind
或>>=
)。(第三项操作是将当前的传送带取走,将其内含物扔掉,然后启动一个新的传送带,称为
>>
,但很少使用。)为了使机器和输送机正常工作,您需要确保:
- 如果将某些东西放在传送带上并使其通过机器,则输出应与手动将其通过机器时的输出相同。(左身份)
- 如果要将传送带放在已经存在的传送带之间,则不应以顶部带有传送带的传送带结尾,而应使用一条更长的传送带。 (正确身份)
- 如果您手动使用机器A,然后将结果传递到连接传送带的BC,或者如果您使用机器,将结果传递给连接的AB,然后手动将结果传递给C,则对于输出无所谓。 >> = b)>> = c)应该与(a >> =(b >> = c))相同(关联性)
最简单的传送带就是那种只接受输入并始终继续到下一个表达式的传送带。这就是“管道”。
另一种可能性是,只有在满足该条件的条件下,才让它通过下一台机器。这意味着,如果在它们之间的某些表达式中,该值更改为不再允许的值,则将跳过其余的表达式。这就是“也许”单子在Haskell中所做的事情。
您还可以在将值传递到计算机之前或之后对值执行其他特殊的条件性复制/更改规则。一个示例:解析器(此处,如果表达式返回“失败”结果,则将表达式之前的值 用作输出)。
当然,这个比喻不是完美的,但我希望它能很好地说明单子的工作原理。
但是,我很难理解这种类比,以理解Comonads。我从互联网上发现的少量信息中得知Comonad定义了以下信息:
extract
,这与的相反return
,也就是说,它从 Comonad中取出一个值。duplicate
,这与的倒数相同join
,也就是说,它从一个中创建了两个Comonad。
但是,如果我们只能从它们中提取或复制它们,该如何实例化Comonad?以及如何实际使用它们?我已经看到了这个非常了不起的项目以及有关它的讨论(很遗憾,我对此了解很少),但是我不确定Comonad到底提供了部分功能。
什么是Comonad?它们有什么用?如何使用它们?它们可食用吗?
cobind
应用程序的开头生成一个comonadic值,那么请反过来说,必须有一些函数可以对comonad的内部表示起作用。