6

SO上,解释了为什么像 scalaz、cats (Scala) 或 Arrow (Kotlin) 这样的验证不能是 monad。

据我了解,这是因为他们已经根据应用函子对 monad 进行了建模,并且 Validation 作为应用程序(收集所有无效)的所需行为与 Validation 作为 monad 的所需行为不同(序列验证并在首先无效)。因此,当您希望快速失败时,您需要将验证转换为 any(这是一个 monad)。

https://groups.google.com/forum/#!msg/scalaz/IWuHC0nlVws/syRUkXJklWIJ上,他们提到验证不是单子的原因,是因为以下属性不成立:

x <|*|> y === x >>= (a => y map ((a, _))) 

但是看看 monad 的定义,上面的属性不是monad 法则的一部分。那么,这是因为 monad 是根据应用程序实现的,还是上述属性是成为 monad 的先决条件?

这种更高层次的推理对我来说都是新事物,但在我对 FP 的有限理解中,我可以有一个验证数据类型,它在用作应用程序(累积无效)时具有一种行为,而在用作 monad 时具有另一种行为(快速失败)。

4

1 回答 1

6

你已经把所有的部分都做好了。是的,一个合法的单子实例 forValidation是可能的。问题是它会产生两个不同Applicative的实例Validation:一个累积错误,另一个从 monad 实例派生并且快速失败。这将导致类型类不一致:程序行为取决于类型类实例是如何到达的。

你提到的房产,

x <|*|> y === x >>= (a => y map ((a, _)))

可以作为 和 的定义<|*|>>>=因此map对于从 Monad 派生的 Applicative 自动成立。问题是已经有一个不同的应用程序具有不同的行为<|*|>

于 2018-05-04T12:54:00.563 回答