I'm using Scalaz 7's EitherT to construct for-comprehensions that blend State and \/. So far so good; I get something that's basically:

State[MyStateType, MyLeftType \/ MyRightType]

and that allows me to build for-comprehensions that have nice variables on the left side of the <-.

But I can't figure out how to return tuples from a state action. Single results are just fine - in the code below, "val comprehension" is exactly what I want to happen.

But things fall apart when I want to return a tuple; "val otherComprehension" won't let me do

(a, b) <- comprehension

It looks like it expects the left side of the \/ to be a Monoid and I don't understand why. What am I missing?

(Scalaz 7 2.0.0-SNAPSHOT, Scala 2.10.2)

object StateProblem {
  case class MyStateType
  case class MyRightType
  case class MyLeftType

  type StateWithFixedStateType[+A] = State[MyStateType, A]
  type EitherTWithFailureType[F[+_], A] = EitherT[F, MyLeftType, A]
  type CombinedStateAndFailure[A] = EitherTWithFailureType[StateWithFixedStateType, A]

  def doSomething: CombinedStateAndFailure[MyRightType] = {
    val x = State[MyStateType, MyLeftType \/ MyRightType] {
      case s => (s, MyRightType().right)
    }
    EitherT[StateWithFixedStateType, MyLeftType, MyRightType](x)
  }

  val comprehension = for {
    a <- doSomething
    b <- doSomething
  } yield (a, b)

  val otherComprehension = for {
    // this gets a compile error:
    // could not find implicit value for parameter M: scalaz.Monoid[com.seattleglassware.StateProblem.MyLeftType]
    (x, y) <- comprehension

    z <- doSomething
  } yield (x, y, z)
}

Edit: I've added evidence that MyLeftType is a monad, even though it's not. In my real code, MyLeftType is a case class (called EarlyReturn), so I can provide a zero, but append only works if one of the arguments is a zero:


                    
                    
                    
Edit
Report