```final case class WriterT[F[_], W, A](run: F[(W, A)]) { self =>
...```

Writer是WriterT的一个F[_] >>> Id特例，那么它的款式也可以被视作这样：

`final case class Writer[W, A](run: (W, A)) { self =>`

```  def flatMap[B](f: A => WriterT[F, W, B])(implicit F: Bind[F], s: Semigroup[W]): WriterT[F, W, B] =
flatMapF(f.andThen(_.run))

def flatMapF[B](f: A => F[(W, B)])(implicit F: Bind[F], s: Semigroup[W]): WriterT[F, W, B] =
writerT(F.bind(run){wa =>
val z = f(wa._2)
F.map(z)(wb => (s.append(wa._1, wb._1), wb._2))
})```

```  type StateT[F[_], S, A] = IndexedStateT[F, S, S, A]
type IndexedState[-S1, S2, A] = IndexedStateT[Id, S1, S2, A]
/** A state transition, representing a function `S => (S, A)`. */
type State[S, A] = StateT[Id, S, A]```

State是StateT的Id特殊案例，而StateT又是IndexedStateT的S1=S2特殊案例。那我们就从最概括的类型IndexedStateT开始介绍吧。下面是IndexedStateT的定义：scalaz/StateT.scala

```trait IndexedStateT[F[_], -S1, S2, A] { self =>
/** Run and return the final value and state in the context of `F` */
def apply(initial: S1): F[(S2, A)]

/** An alias for `apply` */
def run(initial: S1): F[(S2, A)] = apply(initial)

/** Calls `run` using `Monoid[S].zero` as the initial state */
def runZero[S <: S1](implicit S: Monoid[S]): F[(S2, A)] =
run(S.zero)

/** Run, discard the final state, and return the final value in the context of `F` */
def eval(initial: S1)(implicit F: Functor[F]): F[A] =
F.map(apply(initial))(_._2)

/** Calls `eval` using `Monoid[S].zero` as the initial state */
def evalZero[S <: S1](implicit F: Functor[F], S: Monoid[S]): F[A] =
eval(S.zero)

/** Run, discard the final value, and return the final state in the context of `F` */
def exec(initial: S1)(implicit F: Functor[F]): F[S2] =
F.map(apply(initial))(_._1)

/** Calls `exec` using `Monoid[S].zero` as the initial state */
def execZero[S <: S1](implicit F: Functor[F], S: Monoid[S]): F[S2] =
exec(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)
})```

```object IndexedStateT extends StateTInstances with StateTFunctions {
def apply[F[_], S1, S2, A](f: S1 => F[(S2, A)]): IndexedStateT[F, S1, S2, A] = new IndexedStateT[F, S1, S2, A] {
def apply(s: S1) = f(s)
}
}```

```trait MonadState[F[_,_],S] extends Monad[({type f[x]=F[S,x]})#f] {
def state[A](a: A): F[S, A] = bind(init)(s => point(a))
def constantState[A](a: A, s: => S): F[S, A] = bind(put(s))(_ => point(a))
def init: F[S, S]
def get: F[S, S]
def gets[A](f: S => A): F[S, A] = bind(init)(s => point(f(s)))
def put(s: S): F[S, Unit]
def modify(f: S => S): F[S, Unit] = bind(init)(s => put(f(s)))
}

def apply[F[_,_],S](implicit F: MonadState[F, S]) = F
}```

```private trait StateTMonadState[S, F[_]] extends MonadState[({type f[s, a] = StateT[F, s, a]})#f, S] {

def bind[A, B](fa: StateT[F, S, A])(f: A => StateT[F, S, B]): StateT[F, S, B] = fa.flatMap(f)

def point[A](a: => A): StateT[F, S, A] = {
lazy val aa = a
StateT(s => F.point(s, aa))
}

def init: StateT[F, S, S] = StateT(s => F.point((s, s)))

def get = init

def put(s: S): StateT[F, S, Unit] = StateT(_ => F.point((s, ())))

override def modify(f: S => S): StateT[F, S, Unit] = StateT(s => F.point((f(s), ())))

override def gets[A](f: S => A): StateT[F, S, A] = StateT(s => F.point((s, f(s))))
}```

```   type Stack = List[Int]
def pop: State[Stack, Int] = State { case h::t => (t,h) }
//> pop: => scalaz.State[Exercises.stateT.Stack,Int]
def push(a: Int): State[Stack, Unit] = State { xs => (a :: xs, ()) }
//> push: (a: Int)scalaz.State[Exercises.stateT.Stack,Unit]```

```  val prg = for {
_ <- push()
_ <- push()
_ <- push()
a <- pop
b <- get
_ <- pop
_ <- put(List())
} yield b                                       //> prg  : scalaz.IndexedStateT[scalaz.Id.Id,Exercises.stateT.Stack,List[Int],E
prg.run(List())                                 //> res2: scalaz.Id.Id[(List[Int], Exercises.stateT.Stack)] = (List(9),List(2,
//| 1))```

prg只是一段功能描述，因为状态运算函数是个lambda: s => (s,a)。这里s是个未知数，它在for loop里逐层传递下去。运算结果需要通过运行run函数并提供初始状态值List()后才能获取，也就是说真正的运算是在运行run时才开始的。我们称run为程序prg的翻译器（interpreter），这是函数式编程的典型模式，这样可以把具体运算延到最后。

```   val prg = for {
_ <- push()
_ <- push()
_ <- push()
a <- pop
b <- get     //(s,s)
c <- gets { s:Stack => s.length} //(s,s.length)
_ <- pop
_ <- put(List())  //(List(9),a)
_ <- modify {s:Stack => s ++ List() } //(List(9,10),a)
} yield c                                       //> prg  : scalaz.IndexedStateT[scalaz.Id.Id,Exercises.stateT.Stack,List[Int],I
prg.run(List())                                 //> res2: scalaz.Id.Id[(List[Int], Int)] = (List(9, 10),2)```

``` val prg1 = for {
_ <- push()
_ <- push()
_ <- push()
a <- pop
b <-  ) put(List(,,)) ,,))
} yield b                                       //> prg1  : scalaz.IndexedStateT[scalaz.Id.Id,Exercises.stateT.Stack,List[Int],
//| Unit] = scalaz.IndexedStateT\$\$anon\$10@3349e9bb
prg1.run(List())                                //> res4: scalaz.Id.Id[(List[Int], Unit)] = (List(1, 2, 3),())```

```private trait StateTMonadStateMonadPlus[S, F[_]] extends StateTMonadState[S, F] with StateTHoist[S] with MonadPlus[({type λ[α] = StateT[F, S, α]})#λ] {

def empty[A]: StateT[F, S, A] = liftM[F, A](F.empty[A])

def plus[A](a: StateT[F, S, A], b: => StateT[F, S, A]): StateT[F, S, A] = StateT(s => F.plus(a.run(s), b.run(s)))
}```

```  def liftM[G[_], A](ga: G[A])(implicit G: Monad[G]): StateT[G, S, A] =
StateT(s => G.map(ga)(a => (s, a)))```

IndexedStateT还有一个挺有趣的函数lift。在FP风格里lift总是起到搭建OOP到FP通道的作用。我们先来看个例子：

```  def incr: State[Int,Int] = State { s => (s+,s)}//> incr: => scalaz.State[Int,Int]
incr.replicateM().evalZero[Int]               //> res3: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)```

`  incr.replicateM().runZero[Int]             //> java.lang.StackOverflowError`

```  def lift[M[_]: Applicative]: IndexedStateT[({type λ[α]=M[F[α]]})#λ, S1, S2, A] = new IndexedStateT[({type λ[α]=M[F[α]]})#λ, S1, S2, A] {
def apply(initial: S1): M[F[(S2, A)]] = Applicative[M].point(self(initial))
}```

```  import scalaz.Free.Trampoline
incr.lift[Trampoline].replicateM().evalZero[Int]
//> res4: scalaz.Free[Function0,List[Int]] = Gosub()```

```  import scalaz.Free.Trampoline
incr.lift[Trampoline].replicateM().evalZero[Int].run.take()
//> res4: List[Int] = List(0, 1, 2, 3, 4)```

```  def zipIndex[A](xs: List[A]): List[(A, Int)] =
xs.foldLeft(State.state[Int,List[(A,Int)]](List()))(
(acc, a) => for {
xn <- acc
n <- get[Int]
_ <- put[Int](n+)
} yield (a,n) :: xn).evalZero.reverse        //> zipIndex: [A](xs: List[A])List[(A, Int)]

zipIndex( |-> )                               //> res5: List[(Int, Int)] = List((1,0), (2,1), (3,2), (4,3), (5,4))```

```  def zipIndex[A](xs: List[A]): List[(A, Int)] =
xs.foldLeft(State.state[Int,List[(A,Int)]](List()))(
(acc, a) => for {
xn <- acc
n <- get[Int]
_ <- put[Int](n+)
} )
//> zipIndex: [A](xs: List[A])List[(A, Int)]

zipIndex( |-> )                            //> res5: List[(Int, Int)] = List((1,0), (2,1), (3,2), (4,3), (5,4), (6,5), (7,
//| 6), (8,7), (9,8), (10,9))```

```object StateTUsage extends App {
import StateT._

def f[M[_]: Functor] {
Functor[({type l[a] = StateT[M, Int, a]})#l]
}

Applicative[({type l[a] = StateT[M, Int, a]})#l]
Monad[({type l[a] = StateT[M, Int, a]})#l]
MonadState[({type f[s, a] = StateT[M, s, a]})#f, Int]
}

def state() {
val state: State[String, Int] = State((x: String) => (x + , ))
val eval: Int = state.eval("")
state.flatMap(_ => state)
}

}```

``` import Scalaz._
import scala.language.higherKinds

def f[M[_]: Functor] {
Functor[({type l[a] = StateT[M, Int, a]})#l]
}                                               //> f: [M[_]](implicit evidence\$2: scalaz.Functor[M])Unit

Applicative[({type l[a] = StateT[M, Int, a]})#l]
Monad[({type l[a] = StateT[M, Int, a]})#l]
MonadState[({type f[s, a] = StateT[M, s, a]})#f, Int]
}                                               //> m: [M[_]](implicit evidence\$3: scalaz.Monad[M])Unit

def state() {
val state: State[String, Int] = State((x: String) => (x + , ))
val eval: Int = state.eval("")
state.flatMap(_ => state)
}                                               //> state: ()Unit

f[List]
m[List]
state```

``` //Functor实例
val fs = Functor[({type l[a] = StateT[List, Int, a]})#l]
//> fs  : scalaz.Functor[[a]scalaz.IndexedStateT[[+A]List[A],Int,Int,a]] = scala
//| z.StateTInstances1\$\$anon\$1@12468a38
State[Int,Int] {s => (s+,s)}                    //> res0: scalaz.State[Int,Int] = scalaz.package\$State\$\$anon\$3@1aa7ecca
val st = StateT[List, Int, Int](s => List((s,s)))//> st  : scalaz.StateT[List,Int,Int] = scalaz.package\$StateT\$\$anon\$1@6572421
fs.map(st){a => a + }.run()                    //> res1: List[(Int, Int)] = List((0,1))
val ms = MonadState[({type f[s, a] = StateT[List, s, a]})#f, Int]
//> ms  : scalaz.MonadState[[s, a]scalaz.IndexedStateT[[+A]List[A],s,s,a],Int] =
//|  scalaz.StateTInstances1\$\$anon\$1@3c19aaa5
ms.state().run()                               //> res2: List[(Int, Int)] = List((0,1))
//| az.StateTInstances1\$\$anon\$1@689604d9
//Applicative实例                                  //> res3: List[(Int, Int)] = List((0,0))
val ap = Applicative[({type l[a] = StateT[List, Int, a]})#l]
//> ap  : scalaz.Applicative[[a]scalaz.IndexedStateT[[+A]List[A],Int,Int,a]] = s
//| calaz.StateTInstances1\$\$anon\$1@18078bef
ap.point().run()                               //> res4: List[(Int, Int)] = List((0,0))```

``` // def state() {
//构建一个State实例。每次它的状态会加个!符号
val state: State[String, Int] = State((x: String) => (x + ))
//> state  : scalaz.State[String,Int] = scalaz.package\$State\$\$anon\$3@1e67b872
//运算值不变
val eval: Int = state.eval("")                //> eval  : Int = 0
//连续两次运行状态运算函数。加两个!
state.flatMap(_ => state).run("haha")         //> res0: scalaz.Id.Id[(String, Int)] = (haha!!,0)
// }```

```trait Cache
trait FollowerState
def followerState(user: String, cache: Cache): (Cache, FollowerState) = {
val (c1,ofs) = checkCache(user,cache)  //检查cache里有没有user资料
//c1是新cache,更新了hit或miss count
ofs match {  //在cache里找到否
case Some(fs) => (c1,fs)  //找到就返回fs和新cache c1
case None => retrieve(user,c1) //找不到就从数据库里重新读取
}
}
//检查cache，更新cache hit/miss count
def checkCache(user: String, cache: Cache): (Cache, Option[FollowerState]) = ...
//从数据库读取user资料，更新加入cache
def retrieve(user: String, cache: Cache): (Cache, FollowerState) = ...```

```def followerState(user: String, cache: Cache): (Cache, FollowerState)
def followerState(user: String)(cache: Cache): (Cache, FollowerState)
def followerState(user: String): Cache => (Cache, FollowerState)```

```def checkCache(user: String): Cache => (Cache, Option[FollowerState]) = ...
def retrieve(user: String): Cache => (Cache, FollowerState) = ...```

```def followerState(user: String): Cache => (Cache, FollowerState) = cache => {
val (c1,ofs) = checkCache(user,cache)
ofs match {
case Some(fs) => (c1,fs)
case None => retrieve(user,c1)
}
}```

```def followerState(user: String): State[Cache,FollowerState] = State {
cache => {
val (c1,ofs) = checkCache(user,cache)
ofs match {
case Some(fs) => (c1,fs)
case None => retrieve(user,c1)
}
}
}```

```def checkCache(user: String): State[Cache,Option[FollowerState]] = ...
def retrieve(user: String): State[Cache,FollowerState] = ...```

```def followerState(user: String): State[Cache,FollowerState] = for {
optfs <- checkCache(user)
fs <- optfs match {
case Some(fs) => State{ s => (s, fs) }
case None => retrieve(user)
}
} yield fs```

`followerState("Johny Depp").eval(emptyCache)`

1. 泛函编程（17）－泛函状态－State In Action

对OOP编程人员来说,泛函状态State是一种全新的数据类型.我们在上节做了些介绍,在这节我们讨论一下State类型的应用:用一个具体的例子来示范如何使用State类型.以下是这个例子的具体描述: 模 ...

由于泛函编程非常重视函数组合(function composition),任何带有副作用(side effect)的函数都无法实现函数组合,所以必须把包含外界影响(effectful)副作用不纯代码( ...

在上节我们介绍了Trampoline.它主要是为了解决堆栈溢出(StackOverflow)错误而设计的.Trampoline类型是一种数据结构,它的设计思路是以heap换stack:对应传统递归算法 ...

经过了一段时间的学习,我们了解了一系列泛函数据类型.我们知道,在所有编程语言中,数据类型是支持软件编程的基础.同样,泛函数据类型Foldable,Monoid,Functor,Applicative, ...

5. 泛函编程（16）－泛函状态－Functional State

初接触泛函状态觉着很不习惯.主要是在使用State数据类型时很难理解其中的原理,特别是泛函状态变迁机制(state transition mechanism):怎么状态就起了变化,实在难以跟踪.我想这 ...

6. 二十四种设计模式：状态模式(State Pattern)

状态模式(State Pattern) 介绍允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它所属的类. 示例有一个Message实体类,对它的操作有Insert()和Get()方法, ...

7. 乐在其中设计模式(C#) - 状态模式(State Pattern)

原文:乐在其中设计模式(C#) - 状态模式(State Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 状态模式(State Pattern) 作者:webabcd 介绍 允 ...

8. C#设计模式——状态模式(State Pattern)

一.概述在面向对象软件设计时,常常碰到某一个对象由于状态的不同而有不同的行为.如果用if else或是switch case等方法处理,对象操作及对象的状态就耦合在一起,碰到复杂的情况就会造成代码结构 ...

9. 【转】设计模式 ( 十七) 状态模式State（对象行为型）

设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...

## 随机推荐

1. JavaScript css-dom

HTML负责结构层,网页的结构层由HTML或者XHTML之类的标记语言负责构建 CSS负责表示层,描述页面内容应该如何呈现. JavaScript负责行为层,负责内容应该如何响应事件这一问题. 能利用 ...

2. javascript: parse JSON

\$.get("/intra/do/sequence_has_codonList.pl",function(data){ data = JSON.parse(data); // ar ...

3. VIM常用设置

批量替换:  #:%s/source_pattern/target_pattern/g "My Custom Configuration filetype plugin indent on ...

4. svn: Commit failed (details follow): svn: Authorization failed

5. zabbix3.0.4 部署之一 （简介）

6. JPA 不在 persistence.xml 文件中配置每个Entity实体类的2种解决办法

在Spring 集成 Hibernate 的JPA方式中,需要在persistence配置文件中定义每一个实体类,这样非常地不方便,远哥目前找到了2种方法.   这2种方式都可以实现不用persist ...

7. PHP+jQuery 注册模块的改进之三：使用 Smarty3

Smarty3.1X( 最新版本 3.1.19) 比起Smarty2.x修改了不少特性.我把这个模块使用Smarty3.1.18 ( 下载地址http://www.smarty.net/files/S ...

8. 学习之道-从求和起-求和曲线面积瞬时速率极限微积分---求和由高解低已知到未知高阶到低阶连续自然数的K次方之和

数学分析 张筑生

9. C#中 StringBuilder类 与 String类的区别---（转）

在找工作的时候,去了些公司,避免不了要面试和笔试.不过一般最起初的是笔试.我印象中有这样有一道题目:StringBuilder类与 String类的区别?那时候我不太清楚这两个类的区别,今天在看代 ...

10. 自己动手，丰衣足食。普通键盘实现键盘宏（Windows和Mac版）

很多高端机械键盘,支持宏定义,例如我们可以设置"D"键为"dota",这样当我们按一下宏开启键,再按一下"D"键,就等价于分别按了" ...