【问题标题】:Combine IO and State Monad in Scalaz在 Scalaz 中结合 IO 和 State Monad
【发布时间】:2015-05-13 19:28:54
【问题描述】:

我正在尝试使用 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,?,?]

【问题讨论】:

    标签: scala scalaz


    【解决方案1】:

    你不能直接这样做,但是 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],您可以使用acc.exec(whatever) 将其转换为IO 操作。

    值得注意的是,您的代码可以稍微清理一下——例如,init 是不必要的,如果您要丢弃 modify 中的参数等,最好使用 put。还值得注意的是,在实践中,IORef 之类的东西在这里可能更实用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-07
      • 1970-01-01
      • 1970-01-01
      • 2017-03-28
      • 1970-01-01
      • 2019-10-29
      相关资源
      最近更新 更多