2017-03-19 10 views
1

私はリストモナドList[Int]を持っています。私は、リストの値に基づいてエフェクト(Disjunctionとstate)を生成したい。ここに私のモナドスタックと、モナドスタックを実行するコードがあります。私の質問は、私が正しい効果を生成できるようにcheckNumを定義する適切な方法でなければならないものです。どのようにしてMonad Stack of State、Disjunction、およびListの関数を定義できますか?

私の予想される出力は、私の意見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("") 
+0

> 2つのモナドでの作業は、EFFまたはEMMを試し、Scalaで扱いにくいです。 – Reactormonk

答えて

0

は返す必要がありますする必要がありState[String, \/[Throwable,Int]]

val prg = for { 
    x <- lst.liftM[StateTH].liftM[EitherTH] 
    y <- EitherT(checkNum1(x)) 
} yield y 

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] 

次に、あなたとあなたのために、理解を書くことができます

出力:

List(
    ("", \/-(1)), 
    ("Error: 2", -\/(java.lang.Throwable)), 
    ("", \/-(3)), 
    ("Error: 4", -\/(java.lang.Throwable)) 
) 
関連する問題