On SO解释了为什么 scalaz、cats (Scala) 或 Arrow (Kotlin) 中的 Validation 不能是 monad。
据我了解,这是因为他们根据应用函子对单子进行了建模,并且作为应用的验证的所需行为(收集所有无效值)与作为单子的验证的所需行为不同(序列验证并在首先无效)。因此,当您想要快速失败时,您需要将验证转换为任一(这是一个单子)。
On https://groups.google.com/forum/#!msg/scalaz/IWuHC0nlVws/syRUkXJklWIJ,他们提到验证不是 monad 的原因是因为以下属性不成立:
x <|*|> y === x >>= (a => y map ((a, _)))
但看看 monad 的定义,上面的属性并不属于单子法则。那么,这是 monad 是根据应用程序实现的结果,还是上述属性是成为 monad 的先决条件?
这种更高层次的推理对我来说都是全新的,但以我对 FP 的有限理解,我可以拥有一种验证数据类型,该验证数据类型在用作应用程序时具有一种行为(累积无效值),而在用作 monad 时具有另一种行为(快速失败)。
你已经把所有的部分都做好了。是的,一个合法的 monad 实例Validation
是可能的。问题是它会产生两个不同的Applicative
的实例Validation
:一个累积错误,另一个源自 monad 实例并快速失败。这将导致类型类不一致:程序行为取决于类型类实例的到达方式。
你提到的房产,
x <|*|> y === x >>= (a => y map ((a, _)))
可以作为定义<|*|>
按照>>=
and map
,因此对于从 Monad 派生的 Applicative 自动成立。问题是已经有一个不同的 Applicative 具有不同的行为<|*|>
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)