Search code examples
scalascalazfor-comprehension

scalaz's disjuntion gives error if type annotation is given in for comprehensin


Scalaz wants a Monoid instance if I give a type annotation for v1_b in the for comprehension below.

1) Why is that ?

2) The error also mentions filter , how does filter come into this picture ?

import scalaz._
import Scalaz._

case class MyError(s:String)

type Err=MyError
val v1: \/[Err, String] = "cool".right
val v2: \/[Err, String] = MyError("not cool").left[String]

val res: \/[Err, (String,String)] =for {
  v1_a <- v1 // this works fine

  // v1_b : String <- v1
  // uncommenting the line above gives the following compiler error:
  // Error:(23, 22) could not find implicit value for parameter M: scalaz.Monoid[_experiment.scalaz.Disjunction.Err]
  // Error:(23, 22) not enough arguments for method filter: (implicit M: scalaz.Monoid[_experiment.scalaz.Disjunction.Err])scalaz.\/[_experiment.scalaz.Disjunction.Err,String].
  // Unspecified value parameter M.

  v2_ <- v2
} yield (v1_a,v2_)

println(res)

Try this code online in this fiddle : https://scalafiddle.io/sf/DHO6xki/3


Solution

  • v1_b : String performs a type test at runtime. Therefore, the desugaring of this for comprehension has filter in it (to filter out cases when the test fails). filter on \/ requires the left side to be a monoid.