问题
I've got a list monad List[Int]
. I want to generate effects (Disjunction, and state) based on the values of the list. Here is my monad stack and the code to run the monad stack. My question is what should be proper way define checkNum so that I can generate the correct effects?
My expected output shouldList(("", \/-(1), ("Error: 2", -\/(Throwable())), ("",\/-(3)), ("Error: 4", -\/(Throwable())))
import scalaz._
import Scalaz._
type EitherTH[F[_], A] = EitherT[F, Throwable,A]
type StateTH[F[_], A] = StateT[F, String, A]
type StateTList[A] = StateTH[List, A]
type EitherTStateTList[A] = EitherTH[StateTList, A]
val lst = List(1,2,3,4)
def checkNum(x:Int)(implicit ms:MonadState[EitherTStateTList, Int]) = if ((x%2)==0) {
put(s"Error: $x")
-\/(new Throwable())
} else {
put("")
\/-(x)
}
val prg = for {
x <- lst.liftM[StateTH].liftM[EitherTH]
// y <- checkNum(x).liftM[EitherTH]
} yield y
prg.run("")
回答1:
In my opinion checkNum
should return a State[String, \/[Throwable,Int]]
:
def checkNum0(x: Int): State[String, \/[Throwable,Int]] = if ((x%2)==0) {
constantState(-\/(new Throwable()), s"Error: $x")
} else {
constantState(\/-(x), "")
}
def checkNum1(x: Int): StateTList[\/[Throwable,Int]] = checkNum0(x).lift[List]
Then you can write your for-comprehension as:
val prg = for {
x <- lst.liftM[StateTH].liftM[EitherTH]
y <- EitherT(checkNum1(x))
} yield y
Output:
List(
("", \/-(1)),
("Error: 2", -\/(java.lang.Throwable)),
("", \/-(3)),
("Error: 4", -\/(java.lang.Throwable))
)
来源:https://stackoverflow.com/questions/42890099/how-do-i-define-a-function-for-a-monad-stack-of-state-disjunction-and-list