为什么验证会违反monad法律?

时间:2018-05-04 11:54:41

标签: monads scalaz applicative scala-cats arrow-kt

SO上给出了一个解释,为什么像scalaz,cat(Scala)或Arrow(Kotlin)这样的验证不能成为monad。

据我所知,这是因为他们根据应用函子和所需的验证行为对monad进行建模,因为应用(收集所有残留物)与验证为monad的所需行为不同(序列验证和失败)第一次无效的快速)。因此,当您希望快速发生故障时,您需要将验证转换为其中一个(这是一个monad)。

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

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

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

这种更高级的推理对我来说都是新的,但是由于我对FP的理解有限,我可以使用一种验证数据类型,当用作应用程序(累积invalids)时有一种行为,而另一种行为用作monad(快速失败)。

1 个答案:

答案 0 :(得分:5)

你已经把所有的东西都搞定了。是的,Validation的合法monad实例是可能的。问题是它会为Applicative产生两个不同的Validation个实例:一个累积错误,另一个从monad实例派生并快速失败。这会导致类型类不一致:程序行为取决于类型类实例的到达方式。

你提到的财产,

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

可以用<|*|>>>=作为map的定义,因此可以自动保留从Monad派生的Applicative。问题是,<|*|>的行为已经有了不同的适用性。