Question

an example use case:

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

error: Unable to unapply type scalaz.Validation[String,Int] into a type constructor of kind M[_] that is classified by the type class scalaz.Bind

I guess the error is caused by the compiler can't find a Monad instance for Validation[String, Int]

I can make one for myself, like:

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
}
}

but why doesn't Validation have it already? after all, Validation already has the bind method defined.

moreover, I can't have import Validation._ and import Instances._ together anymore (this took me looong to figure out...), because of another complicated error...
ambiguous implicit values: something like both validationMonad (my instance), and method ValidationInstances1 in trait ValidationInstances2... both match some Functor of Validation...

should I modify the source of scalaz? or I'm completely missing something~?
please help~

I'm using scalaz 7.0.0-M2

Was it helpful?

Solution

As discussed in the Scalaz group, the problem seems to be that ap would accumulate errors whereas (pseudo-)monadic composition would only operate on the value part of Validation.

Therefore, one cannot be expressed in terms of the other and thus no monad instance exists for Validation.

OTHER TIPS

The issue is that the applicative functor as implied by the monad does not equal the actual applicative functor

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top