如何为状态、分离和列表的 Monad 堆栈定义函数?
How do I define a function for a Monad Stack of State, Disjunction, and List?
我有一个列表 monad List[Int]
。我想根据列表的值生成效果(析取和状态)。这是我的 monad 堆栈和 运行 monad 堆栈的代码。我的问题是应该怎样定义 checkNum 才能产生正确的效果?
我的预期输出应该
List(("", \/-(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("")
我认为 checkNum
应该 return 一个 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]
那么你的理解力可以写成:
val prg = for {
x <- lst.liftM[StateTH].liftM[EitherTH]
y <- EitherT(checkNum1(x))
} yield y
输出:
List(
("", \/-(1)),
("Error: 2", -\/(java.lang.Throwable)),
("", \/-(3)),
("Error: 4", -\/(java.lang.Throwable))
)
我有一个列表 monad List[Int]
。我想根据列表的值生成效果(析取和状态)。这是我的 monad 堆栈和 运行 monad 堆栈的代码。我的问题是应该怎样定义 checkNum 才能产生正确的效果?
我的预期输出应该
List(("", \/-(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("")
我认为 checkNum
应该 return 一个 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]
那么你的理解力可以写成:
val prg = for {
x <- lst.liftM[StateTH].liftM[EitherTH]
y <- EitherT(checkNum1(x))
} yield y
输出:
List(
("", \/-(1)),
("Error: 2", -\/(java.lang.Throwable)),
("", \/-(3)),
("Error: 4", -\/(java.lang.Throwable))
)