`/*val a = e1val b = e2(a)val c = e3(a,b)val d = e2(c)*/`

` 1 import scalaz._ 2 import Scalaz._ 3 def e1:Id[Int] = 10 //> e1: => scalaz.Scalaz.Id[Int] 4 def e2(a: Int): Id[Int] = a + 1 //> e2: (a: Int)scalaz.Scalaz.Id[Int] 5 def e3(a: Int, b: Int): Id[Int] = a + b //> e3: (a: Int, b: Int)scalaz.Scalaz.Id[Int] 6 for { 7 a <- e1 8 b <- e2(a) 9 c <- e3(a,b)10 d <- e2(c)11 } yield d //> res0: scalaz.Scalaz.Id[Int] = 22`

` 1 import scalaz._ 2 import Scalaz._ 3 def e1:Option[Int] = 10.some //> e1: => Option[Int] 4 def e2(a: Int): Option[Int] = (a + 1).some //> e2: (a: Int)Option[Int] 5 def e3(a: Int, b: Int): Option[Int] = (a + b).some//> e3: (a: Int, b: Int)Option[Int] 6 for { 7 a <- e1 8 b <- e2(a) 9 c <- e3(a,b)10 d <- e2(c)11 } yield d //> res0: Option[Int] = Some(22)`

` 1 import scalaz._ 2 import Scalaz._ 3 def e1:Reader[Int,Int] = Reader[Int,Int](a => a) //> e1: => scalaz.Reader[Int,Int] 4 def e2(a: Int): Reader[Int,Int] = Reader[Int,Int](_ => a + 1) 5 //> e2: (a: Int)scalaz.Reader[Int,Int] 6 def e3(a: Int, b: Int): Reader[Int, Int] = Reader[Int,Int](_ => a+b) 7 //> e3: (a: Int, b: Int)scalaz.Reader[Int,Int] 8 val prg = for { 9 a <- e110 b <- e2(a)11 c <- e3(a,b)12 d <- e2(c)13 } yield d //> prg : scalaz.Kleisli[scalaz.Id.Id,Int,Int] = Kleisli(<function1>)14 prg.run(10) //> res0: scalaz.Id.Id[Int] = 22`

`case class StateT[F[_],S,A](run: S => F[(S,A)])`

` 1 for { 2 a <- 3.some 3 b <- (None: Option[Int]) 4 c <- 4.some 5 } yield c //> res1: Option[Int] = None 6 val statePrg = for { 7 a <- get[Int] 8 b <- State[Int,Int](s => (s, s + a)) 9 _ <- put(9)10 } yield b //> statePrg : scalaz.IndexedStateT[scalaz.Id.Id,Int,Int,Int] = scalaz.IndexedS11 //| [email protected]12 statePrg.run(3) //> res2: scalaz.Id.Id[(Int, Int)] = (9,6)`

` case class OptionState[S,A](run: S => Option[(S,A)]) {def map[B](f: A => B): OptionState[S,B] =OptionState {s => run(s) map { case (s1,a1) => (s1,f(a1)) }}def flatMap[B](f: A => OptionState[S,B]): OptionState[S,B] =OptionState {s => run(s) flatMap { case (s1,a1) => f(a1).run(s1) }}}`

` def liftOption[S,A](oa: Option[A]): OptionState[S,A] = oa match {case Some(a) => OptionState {s => (s,a).some }case None => OptionState {_ => none}}def liftState[S,A](sa: State[S,A]): OptionState[S,A] =OptionState {s => sa(s).some}`

` 1 val osprg: OptionState[Int,Int] = for { 2 a <- liftOption(3.some) 3 b <- liftState(put(a)) 4 c <- liftState(get[Int]) 5 d <- liftState(State[Int,Int](s => (s+c, s+a))) 6 } yield c //> osprg : Exercises.rws.OptionState[Int,Int] = OptionState(<function1>) 7 osprg.run(2) //> res3: Option[(Int, Int)] = Some((6,3)) 8 val osprg1: OptionState[Int,Int] = for { 9 a <- liftOption(3.some)10 b <- liftState(put(a))11 _ <- liftOption((None: Option[Int]))12 c <- liftState(get[Int])13 d <- liftState(State[Int,Int](s => (s+c, s+a)))14 } yield c //> osprg1 : Exercises.rws.OptionState[Int,Int] = OptionState(<function1>)15 osprg1.run(2) //> res4: Option[(Int, Int)] = None`

` type ReaderWriterStateT[F[_], -R, W, S, A] = IndexedReaderWriterStateT[F, R, W, S, S, A]object ReaderWriterStateT extends ReaderWriterStateTInstances with ReaderWriterStateTFunctions {def apply[F[_], R, W, S, A](f: (R, S) => F[(W, A, S)]): ReaderWriterStateT[F, R, W, S, A] = IndexedReaderWriterStateT[F, R, W, S, S, A] { (r: R, s: S) => f(r, s) }}type IndexedReaderWriterState[-R, W, -S1, S2, A] = IndexedReaderWriterStateT[Id, R, W, S1, S2, A]object IndexedReaderWriterState extends ReaderWriterStateTInstances with ReaderWriterStateTFunctions {def apply[R, W, S1, S2, A](f: (R, S1) => (W, A, S2)): IndexedReaderWriterState[R, W, S1, S2, A] = IndexedReaderWriterStateT[Id, R, W, S1, S2, A] { (r: R, s: S1) => f(r, s) }}type ReaderWriterState[-R, W, S, A] = ReaderWriterStateT[Id, R, W, S, A]object ReaderWriterState extends ReaderWriterStateTInstances with ReaderWriterStateTFunctions {def apply[R, W, S, A](f: (R, S) => (W, A, S)): ReaderWriterState[R, W, S, A] = IndexedReaderWriterStateT[Id, R, W, S, S, A] { (r: R, s: S) => f(r, s) }}type IRWST[F[_], -R, W, -S1, S2, A] = IndexedReaderWriterStateT[F, R, W, S1, S2, A]val IRWST: IndexedReaderWriterStateT.type = IndexedReaderWriterStateTtype IRWS[-R, W, -S1, S2, A] = IndexedReaderWriterState[R, W, S1, S2, A]val IRWS: IndexedReaderWriterState.type = IndexedReaderWriterStatetype RWST[F[_], -R, W, S, A] = ReaderWriterStateT[F, R, W, S, A]val RWST: ReaderWriterStateT.type = ReaderWriterStateTtype RWS[-R, W, S, A] = ReaderWriterState[R, W, S, A]val RWS: ReaderWriterState.type = ReaderWriterState`

`case class Reader[R, A](f: R => A) //传入R，返回A后不理会Rcase class Writer[W, A](w: (W, A)) //直接返回W,Acase class State[S, A](f: S => (A, S)) //传入S, 返回A和S`

`case class ReaderWriterState[R, W, S, A](run: (R, S) => (W, A, S) //传入R,S 返回W,A,S)case class ReaderWriterStateT[F[_],R, W, S, A](run: (R, S) => F[(W, A, S)] //传入R,S 返回W,A,S。只是包在了F内) `

`/** A monad transformer stack yielding `(R, S1) => F[(W, A, S2)]`. */sealed abstract class IndexedReaderWriterStateT[F[_], -R, W, -S1, S2, A] {self =>def run(r: R, s: S1): F[(W, A, S2)]/** Discards the writer component. */def state(r: R)(implicit F: Functor[F]): IndexedStateT[F, S1, S2, A] =IndexedStateT((s: S1) => F.map(run(r, s)) {case (w, a, s1) => (s1, a)})/** Calls `run` using `Monoid[S].zero` as the initial state */def runZero[S <: S1](r: R)(implicit S: Monoid[S]): F[(W, A, S2)] =run(r, S.zero)/** Run, discard the final state, and return the final value in the context of `F` */def eval(r: R, s: S1)(implicit F: Functor[F]): F[(W, A)] =F.map(run(r,s)) { case (w,a,s2) => (w,a) }/** Calls `eval` using `Monoid[S].zero` as the initial state */def evalZero[S <: S1](r:R)(implicit F: Functor[F], S: Monoid[S]): F[(W,A)] =eval(r,S.zero)/** Run, discard the final value, and return the final state in the context of `F` */def exec(r: R, s: S1)(implicit F: Functor[F]): F[(W,S2)] =F.map(run(r,s)){case (w,a,s2) => (w,s2)}/** Calls `exec` using `Monoid[S].zero` as the initial state */def execZero[S <: S1](r:R)(implicit F: Functor[F], S: Monoid[S]): F[(W,S2)] =exec(r,S.zero)...`

`def map[B](f: A => B)(implicit F: Functor[F]): IndexedStateT[F, S1, S2, B] = IndexedStateT(s => F.map(apply(s)) {case (s1, a) => (s1, f(a))})def flatMap[S3, B](f: A => IndexedStateT[F, S2, S3, B])(implicit F: Bind[F]): IndexedStateT[F, S1, S3, B] = IndexedStateT(s => F.bind(apply(s)) {case (s1, a) => f(a)(s1)})`

`private trait ReaderWriterStateTMonad[F[_], R, W, S]extends MonadReader[({type λ[r, α]=ReaderWriterStateT[F, r, W, S, α]})#λ, R]with MonadState[({type f[s, α] = ReaderWriterStateT[F, R, W, s, α]})#f, S]with MonadListen[({type f[w, α] = ReaderWriterStateT[F, R, w, S, α]})#f, W]with IndexedReaderWriterStateTFunctor[F, R, W, S, S] {implicit def F: Monad[F]implicit def W: Monoid[W]def bind[A, B](fa: ReaderWriterStateT[F, R, W, S, A])(f: A => ReaderWriterStateT[F, R, W, S, B]): ReaderWriterStateT[F, R, W, S, B] = fa flatMap fdef point[A](a: => A): ReaderWriterStateT[F, R, W, S, A] =ReaderWriterStateT((_, s) => F.point((W.zero, a, s)))def ask: ReaderWriterStateT[F, R, W, S, R] =ReaderWriterStateT((r, s) => F.point((W.zero, r, s)))def local[A](f: R => R)(fa: ReaderWriterStateT[F, R, W, S, A]): ReaderWriterStateT[F, R, W, S, A] =ReaderWriterStateT((r, s) => fa.run(f(r), s))override def scope[A](k: R)(fa: ReaderWriterStateT[F, R, W, S, A]): ReaderWriterStateT[F, R, W, S, A] =ReaderWriterStateT((_, s) => fa.run(k, s))override def asks[A](f: R => A): ReaderWriterStateT[F, R, W, S, A] =ReaderWriterStateT((r, s) => F.point((W.zero, f(r), s)))def init: ReaderWriterStateT[F, R, W, S, S] =ReaderWriterStateT((_, s) => F.point((W.zero, s, s)))def get = initdef put(s: S): ReaderWriterStateT[F, R, W, S, Unit] =ReaderWriterStateT((r, _) => F.point((W.zero, (), s)))override def modify(f: S => S): ReaderWriterStateT[F, R, W, S, Unit] =ReaderWriterStateT((r, s) => F.point((W.zero, (), f(s))))override def gets[A](f: S => A): ReaderWriterStateT[F, R, W, S, A] =ReaderWriterStateT((_, s) => F.point((W.zero, f(s), s)))def writer[A](w: W, v: A): ReaderWriterStateT[F, R, W, S, A] =ReaderWriterStateT((_, s) => F.point((w, v, s)))override def tell(w: W): ReaderWriterStateT[F, R, W, S, Unit] =ReaderWriterStateT((_, s) => F.point((w, (), s)))def listen[A](ma: ReaderWriterStateT[F, R, W, S, A]): ReaderWriterStateT[F, R, W, S, (A, W)] =ReaderWriterStateT((r, s) => F.map(ma.run(r, s)) { case (w, a, s1) => (w, (a, w), s1)})}`

`1 val program: ReaderWriterState[Config, List[String], Int, Int] = for {2 _ <- log("Start - r: %s, s: %s")3 res <- invokeService4 _ <- log("Between - r: %s, s: %s")5 _ <- setService(8,"Com8")6 _ <- invokeService7 _ <- log("Done - r: %s, s: %s")8 } yield res //> program : scalaz.RWS[Exercises.rws.Config,List[String],Int,Int] = scalaz.I9 //| [email protected]`

` 1 case class Config(var port: Int, var portName: String) 2 def log[R, S](msg: String): RWS[R, List[String], S, Unit] = 3  ReaderWriterState { 4 case (r, s) => (msg.format(r, s) :: Nil, (), s) //.point[Identity] 5 } //> log: [R, S](msg: String)scalaz.RWS[R,List[String],S,Unit] 6 def invokeService: ReaderWriterState[Config, List[String], Int, Int] = 7  ReaderWriterState { 8 case (cfg, invocationCount) => ( 9 List("Invoking service with port: " + cfg.portName),10 scala.util.Random.nextInt(100),11 invocationCount + 112 ) //.point[Identity]13 } //> invokeService: => scalaz.ReaderWriterState[Exercises.rws.Config,List[String14 //| ],Int,Int]15 def setService(p: Int, n: String): ReaderWriterState[Config, List[String], Int, Int] =16  ReaderWriterState {17 case (cfg, invocationCount) => cfg.port=p; cfg.portName=n18 (List("Changing service port to " + cfg.portName),19 scala.util.Random.nextInt(100),20  invocationCount)21 } //> setService: (p: Int, n: String)scalaz.ReaderWriterState[Exercises.rws.Confi22 //| g,List[String],Int,Int]2324 val program: ReaderWriterState[Config, List[String], Int, Int] = for {25 _ <- log("Start - r: %s, s: %s")26 res <- invokeService27 _ <- log("Between - r: %s, s: %s")28 _ <- setService(8,"Com8")29 _ <- invokeService30 _ <- log("Done - r: %s, s: %s")31 } yield res //> program : scalaz.RWS[Exercises.rws.Config,List[String],Int,Int] = scalaz.I32 //| [email protected]33 val r = program run (Config(443,"Com3"), 0) //> r : scalaz.Id.Id[(List[String], Int, Int)] = (List(Start - r: Config(443,C34 //| om3), s: 0, Invoking service with port: Com3, Between - r: Config(443,Com3)35 //| , s: 1, Changing service port to Com8, Invoking service with port: Com8, Do36 //| ne - r: Config(88,Com8), s: 2),68,2)37 println("Result: " + r._2) //> Result: 6838 println("Service invocations: " + r._3) //> Service invocations: 239 println("Log: %n%s".format(r._1.mkString("\t", "%n\t".format(), "")))40 //> Log:41 //| Start - r: Config(443,Com3), s: 042 //| Invoking service with port: Com343 //| Between - r: Config(443,Com3), s: 144 //| Changing service port to Com845 //| Invoking service with port: Com846 //| Done - r: Config(88,Com8), s: 2`

Top