为什么不验证Monad?(scalaz7)

Chr*_*ris 25 monads scala scalaz scalaz7

一个用例示例:

def div2(i: Int): Validation[String, Int] = 
    if (i%2 == 0) Validation.success(i/2)
    else Validation.failure("odd")

def div4(i: Int) = for {
    a <- div2(i)
    b <- div2(a)
} yield b
Run Code Online (Sandbox Code Playgroud)

错误:无法取消应用类型scalaz.Validation[String,Int]M[_]由类型类别分类的类型构造函数scalaz.Bind

错误是由编译器无法找到的Monad实例引起的Validation[String, Int]

我可以为自己制作一个,比如:

object Instances {
implicit def validationMonad[E] = new Monad[({type L[A] = Validation[E, A]})#L] {
    override def point[A](a: => A) =
        Validation.success(a)
    override def bind[A, B](fa: Validation[E, A])(f: A => Validation[E, B]) =
        fa bind f
}
}
Run Code Online (Sandbox Code Playgroud)

但为什么还没有Validation呢?毕竟,Validation已经bind定义了方法.

此外,我不能再import Validation._import Instances._在一起了(这让我想出来......),因为另一个复杂的 错误 ......
含糊不清的隐含价值观:两者都有validationMonad(我的实例)和ValidationInstances1特质中的方法ValidationInstances2......两者都匹配Functor of Validation...

我应该修改scalaz的来源吗?或者我完全错过了什么〜?
请帮忙〜

我正在使用scalaz 7.0.0-M2

Deb*_*ski 20

正如Scalaz小组所讨论的那样,问题似乎是ap积累错误,而(伪)monadic组合只会在值的一部分上运行Validation.

因此,不能用另一个来表达,因此不存在monad实例Validation.

  • @chris如果你不关心自动附加失败,一个明显的选择是完全切换到`scalaz.\ /`(Scalaz的右偏置替换`Either`),它具有你想要的语义,因此可能对其他人不那么困惑.(实施一项基本上违反monad和适用法律的规则可能会非常好并且可以预测,但它可能会变得有点令人困惑.) (3认同)
  • 但是作为附带的问题,我的用例是否没有出路?除了自己定义Monad实例之外?我的做法有什么不好的一面吗? (2认同)

oxb*_*kes 6

问题是monad暗示的applicative functor与实际的 applicative functor 不相等

  • 你能解释一下这里隐含的是什么,实际是什么?我不太了解这些类型类的东西...... (8认同)
  • 尊重@oxbow_lakes (2认同)