逃避影响蒙纳德与不逃避

时间:2015-12-15 03:49:49

标签: scala scalaz

这两种功能有何不同?

case class DFStorage(private var cache: Map[String, DataFrame] = Map()) {

  def tryLoad(job: Job): Kleisli[IO, MakeContext, \/[List[String], Unit]] = {
    if(!cache.contains(job.id)) {
      job.tryLoad.map(_.map(df => add(job, df)))
    } else {
      IO(().right[List[String]]).liftKleisli
    }
  }


  def tryLoad(job: Job): Kleisli[IO, MakeContext, \/[List[String], Unit]] = {
    Kleisli({makeContext: MakeContext =>
      if(!cache.contains(job.id)) {
        IO {
          job.tryLoad.run(makeContext).unsafePerformIO().map(df => add(job, df))
        }
      } else {
        IO(().right[List[String]])
      }
    })
  }
}

1 个答案:

答案 0 :(得分:0)

我认为你应该在你的程序中调用unsafePerformIO作为最终副作用(例如在你的主函数中),但是在这种情况下它可能导致同样的事情给出你是"展开" IO monad中的值,然后包装该值的转换。正如您所看到的,此值的展开和转换可能与IO.map执行的过程相同。

unsafePerformIO用于强制执行IO值表示的副作用。在Haskell中,您的程序必须是IO类型并且Haskell运行它(main必须具有类型IO)。但是在Scala中,main函数可以执行任何操作,因此您必须在此时执行IO。