## 动力学知识库

Scalaz的可变量分两种：一个内存地址STRef或一个可变数组STArray。我们先看看它们在源代码中的定义：effect/ST.scala

`/**Mutable variable in state thread S containing a value of type A. [[http://research.microsoft.com/en-us/um/people/simonpj/papers/lazy-functional-state-threads.ps.Z]] */sealed trait STRef[S, A] {protected var value: A/**Reads the value pointed at by this reference. */def read: ST[S, A] = returnST(value)/**Modifies the value at this reference with the given function. */def mod[B](f: A => A): ST[S, STRef[S, A]] = st((s: Tower[S]) => {value = f(value);(s, this)})/**Associates this reference with the given value. */def write(a: => A): ST[S, STRef[S, A]] = st((s: Tower[S]) => {value = a;(s, this)})/**Synonym for write*/def |=(a: => A): ST[S, STRef[S, A]] =write(a)/**Swap the value at this reference with the value at another. */def swap(that: STRef[S, A]): ST[S, Unit] = for {v1 <- this.readv2 <- that.read_ <- this write v2_ <- that write v1} yield ()}.../**Mutable array in state thread S containing values of type A. */sealed trait STArray[S, A] {def size: Intdef z: Aimplicit def manifest: Manifest[A]private lazy val value: Array[A] = Array.fill(size)(z)import ST._/**Reads the value at the given index. */def read(i: Int): ST[S, A] = returnST(value(i))/**Writes the given value to the array, at the given offset. */def write(i: Int, a: A): ST[S, STArray[S, A]] = st(s => {value(i) = a;(s, this)})/**Turns a mutable array into an immutable one which is safe to return. */def freeze: ST[S, ImmutableArray[A]] = st(s => (s, ImmutableArray.fromArray(value)))/**Fill this array from the given association list. */def fill[B](f: (A, B) => A, xs: Traversable[(Int, B)]): ST[S, Unit] = xs match {case Nil => returnST(())case ((i, v) :: ivs) => for {_ <- update(f, i, v)_ <- fill(f, ivs)} yield ()}/**Combine the given value with the value at the given index, using the given function. */def update[B](f: (A, B) => A, i: Int, v: B) = for {x <- read(i)_ <- write(i, f(x, v))} yield ()}`

`/*** Purely functional mutable state threads.* Based on JL and SPJ's paper "Lazy Functional State Threads"*/sealed trait ST[S, A] {private[effect] def apply(s: Tower[S]): (Tower[S], A)import ST._def flatMap[B](g: A => ST[S, B]): ST[S, B] =st(s => apply(s) match {case (ns, a) => g(a)(ns)})def map[B](g: A => B): ST[S, B] =st(s => apply(s) match {case (ns, a) => (ns, g(a))})}`

` 1 import scalaz._2 import Scalaz._3 import effect._4 import ST._5 object st {6 def e1[S] = for {7 r <- newVar[S](3)8 x <- r.mod {_ + 2}9 } yield x //> e1: [S]=> scalaz.effect.ST[S,scalaz.effect.STRef[S,Int]]1011 def e2[S] = for {12 r <- newVar[S](3)13 x <- r.mod {_ + 2}14 y <- x.read15 } yield y //> e2: [S]=> scalaz.effect.ST[S,Int]1617 def e3[S] = for {18 arr <- newArr[S,Int](5,0)19 _ <- arr.write(0,3)20 _ <- arr.write(1,2)21 _ <- arr.update ((a: Int,b: Int) => a + b, 2, 4)22 r <- arr.freeze23 } yield r //> e3: [S]=> scalaz.effect.ST[S,scalaz.ImmutableArray[Int]]`

`1 runST(new Forall[({type l[x] = ST[x, Int]})#l]{def apply[S] = e2[S]})2 //> res0: Int = 53 //runST(new Forall[({type l[x] = ST[x, Int]})#l]{def apply[S] = e1[S]})4 //type mismatch; found : scalaz.effect.ST[S,scalaz.effect.STRef[S,Int]] required: scalaz.effect.ST[S,Int] `

e1返回ST[S,STRef[S,A]]，表达式new Forall[({type l[x] = ST[x, Int]})#l]{def apply[S] = e1[S]}无法通过编译。在这里Forall是个高阶类参数多态类，定义如下：

`/** A universally quantified value */trait Forall[P[_]] {def apply[A]: P[A]}`

`1 type ForallST[A] = Forall[({type l[x] = ST[x,A]})#l]2 runST(new ForallST[Int]{ def apply[S] = e2[S] }) //> res0: Int = 53 //runST(new ForallST[Int]{def apply[S] = e1[S]})4 //type mismatch; found : scalaz.effect.ST[S,scalaz.effect.STRef[S,Int]] required: scalaz.effect.ST[S,Int]`

runST方法的定义如下：

` /**Run a state thread */def runST[A](f: Forall[({type λ[S] = ST[S, A]})#λ]): A =f.apply.apply(ivoryTower)._2`