Permalink
Browse files

Don't pass around fictitious state (IvoryTower) in ST.

  • Loading branch information...
1 parent 5825b15 commit 4d48e86d40c0098c0d2e38b4610d58d4620f240c @TomasMikula TomasMikula committed Jan 28, 2017
Showing with 19 additions and 24 deletions.
  1. +1 −1 effect/src/main/scala/scalaz/effect/IO.scala
  2. +18 −23 effect/src/main/scala/scalaz/effect/ST.scala
@@ -297,7 +297,7 @@ object IO extends IOInstances {
/** An IO action is an ST action. */
implicit def IOToST[A](io: IO[A]): ST[IvoryTower, A] =
- st(io(_).run)
+ st(() => io(ivoryTower).run._2)
/** An IO action that does nothing. */
val ioUnit: IO[Unit] =
@@ -3,7 +3,6 @@ package effect
import reflect.ClassTag
-import IvoryTower._
import STRef._
import STArray._
import ST._
@@ -18,15 +17,15 @@ sealed abstract class STRef[S, A] {
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]) => {
+ def mod[B](f: A => A): ST[S, STRef[S, A]] = st(() => {
value = f(value);
- (s, this)
+ this
})
/**Associates this reference with the given value. */
- def write(a: => A): ST[S, STRef[S, A]] = st((s: Tower[S]) => {
+ def write(a: => A): ST[S, STRef[S, A]] = st(() => {
value = a;
- (s, this)
+ this
})
/**Synonym for write*/
@@ -77,13 +76,13 @@ sealed abstract class STArray[S, A] {
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 => {
+ def write(i: Int, a: A): ST[S, STArray[S, A]] = st(() => {
value(i) = a;
- (s, this)
+ 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)))
+ def freeze: ST[S, ImmutableArray[A]] = st(() => 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 {
@@ -116,40 +115,36 @@ object STArray {
* Based on JL and SPJ's paper "Lazy Functional State Threads"
*/
sealed abstract class ST[S, A] {
- private[effect] def apply(s: Tower[S]): (Tower[S], A)
+ private[effect] def run: 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)
- })
+ st(() => g(run).run)
def map[B](g: A => B): ST[S, B] =
- st(s => apply(s) match {
- case (ns, a) => (ns, g(a))
- })
+ st(() => g(run))
}
object ST extends STInstances {
def apply[S, A](a: => A): ST[S, A] =
returnST(a)
- def st[S, A](f: Tower[S] => (Tower[S], A)): ST[S, A] = new ST[S, A] {
- private[effect] def apply(s: Tower[S]) = f(s)
+ def st[S, A](f: () => A): ST[S, A] = new ST[S, A] {
+ private[effect] def run = f()
}
// Implicit conversions between IO and ST
implicit def STToIO[A](st: ST[IvoryTower, A]): IO[A] =
- IO.io(rw => Free.return_(st(rw)))
+ IO.io(rw => Free.return_((rw, st.run)))
/**Put a value in a state thread */
def returnST[S, A](a: => A): ST[S, A] =
- st(s => (s, a))
+ st(() => a)
/**Run a state thread */
def runST[A](f: Forall[ST[?, A]]): A =
- f.apply.apply(ivoryTower)._2
+ f.apply.run
/**Allocates a fresh mutable reference. */
def newVar[S]: Id ~> λ[α => ST[S, STRef[S, α]]] =
@@ -162,9 +157,9 @@ object ST extends STInstances {
returnST(stArray[S, A](size, z))
/**Allows the result of a state transformer computation to be used lazily inside the computation. */
- def fixST[S, A](k: (=> A) => ST[S, A]): ST[S, A] = st(s => {
- lazy val ans: (Tower[S], A) = k(r)(s)
- lazy val (_, r) = ans
+ def fixST[S, A](k: (=> A) => ST[S, A]): ST[S, A] = ST({
+ lazy val ans: A = k(r).run
+ lazy val r = ans
ans
})

0 comments on commit 4d48e86

Please sign in to comment.