Я пытаюсь понять Monad Transformers в Scala, портируя некоторые примеры из этого урока Дэн Пипони: http://blog.sigfpe.com/2006/05/grok-haskell-monad-transformers.html p >
Я сделал пару простых:
import Control.Monad.State
import Control.Monad.Identity
test1 = do
a <- get
modify (+1)
b <- get
return (a,b)
test2 = do
a <- get
modify (++"1")
b <- get
return (a,b)
go1 = evalState test1 0
go2 = evalState test2 "0"
становится:
import scalaz._, Scalaz._
val test1 = for {
a <- get[Int]
_ <- modify[Int](1+)
b <- get
} yield (a,b)
val test2 = for {
a <- get[String]
_ <- modify[String](_ + "1")
b <- get
} yield (a,b)
val go1 = test1.eval(0)
val go2 = test2.eval("0")
Но как я могу перенести следующий пример на Scala?
test3 = do
modify (+ 1)
lift $ modify (++ "1")
a <- get
b <- lift get
return (a,b)
go3 = runIdentity $ evalStateT (evalStateT test3 0) "0"
Я получил это далеко, используя scalaz 7.1.0-M6:
type SST[F[_],A] = StateT[F,String,A]
type IST[F[_],A] = StateT[F,Int,A]
val p1: StateT[Id,Int,Unit] = modify[Int](1+)
val p2: StateT[Id,String,Unit] = modify[String](_ + "1")
val p3: StateT[({type l[a]=StateT[Id,String,a]})#l,Int,Unit] = p2.liftM[IST]
но это еще не закрыто, и может даже быть назад для всех, что я могу сказать.
Конечно, я могу это сделать:
import scalaz.Lens._
val test3 = for {
_ <- firstLens[Int,String] lifts (modify (1+))
_ <- secondLens[Int,String] lifts (modify (_ + "1"))
a <- firstLens[Int,String] lifts get
b <- secondLens[Int,String] lifts get
} yield (a,b)
val go3 = test3.eval(0,"0")
но тогда я вообще не использую stacked StateT, поэтому он не отвечает на вопрос.
Спасибо заранее!