我正在尝试使用scalaz中的State monad编写一个简单的程序,它将根据用户传入的输入修改某些状态。如何最好地完成。目前我有:
import scalaz._
import Scalaz._
import effect._
import IO._
def acc = for {
i <- init
_ <- modify{s: Int => 100}
v <- readLn
_ <- modify{s: Int => v}
} yield ()
抛出:
<console>:25: error: polymorphic expression cannot be instantiated to expected type;
found : [B]scalaz.effect.IO[B]
required: scalaz.IndexedStateT[scalaz.Id.Id,Int,?,?]
答案 0 :(得分:4)
你不能直接这样做,但monad变压器版本并不太可怕:
import scalaz._, Scalaz._, effect._, IO._
type IS[S, A] = StateT[IO, S, A]
type ISInt[A] = IS[Int, A]
val ms = MonadState[IS, Int]
import ms._
def acc = for {
i <- init
_ <- modify(s => 100)
v <- readLn.liftIO[ISInt]
_ <- modify(s => v.toInt)
} yield ()
这为您提供StateT[IO, Int, Unit]
,您可以使用IO
转换为acc.exec(whatever)
行动。
值得注意的是,您的代码可能会被清理一下 - 例如,init
是不必要的,如果您扔掉,也可以使用put
modify
等中的论据。值得注意的是,实际上像IORef
这样的东西在这里可能更实用。