Skip to content

Commit

Permalink
Add StateT transformS
Browse files Browse the repository at this point in the history
  • Loading branch information
adelbertc committed Jan 5, 2016
1 parent cb2a945 commit 267721a
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
14 changes: 14 additions & 0 deletions core/src/main/scala/cats/state/StateT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ final class StateT[F[_], S, A](val runF: F[S => F[(S, A)]]) extends Serializable
def transformF[G[_], B](f: F[(S, A)] => G[(S, B)])(implicit F: FlatMap[F], G: Applicative[G]): StateT[G, S, B] =
StateT(s => f(run(s)))

/** Transform the state used
*
* This is useful when you are working with many focused `StateT`s and want to pass in a
* global state containing the various states needed for each individual `StateT`.
*/
def transformS[R](f: R => S, g: (R, S) => R)(implicit F: Monad[F]): StateT[F, R, A] =
StateT { r =>
F.flatMap(runF) { ff =>
val s = f(r)
val nextState = ff(s)
F.map(nextState) { case (s, a) => (g(r, s), a) }
}
}

/**
* Modify the state (`S`) component.
*/
Expand Down
17 changes: 17 additions & 0 deletions tests/src/test/scala/cats/tests/StateTTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,23 @@ class StateTTests extends CatsSuite {
}
}

test("StateT#transformS with identity is identity") {
forAll { (s: StateT[List, Long, Int]) =>
s.transformS[Long](identity, (s, i) => i) should === (s)
}
}

test("StateT#transformS modifies state") {
final case class Env(int: Int, str: String)
val x = StateT((x: Int) => Option((x + 1, x)))
val xx = x.transformS[Env](_.int, (e, i) => e.copy(int = i))
val input = 5

val got = x.run(input)
val expected = xx.run(Env(input, "hello")).map { case (e, i) => (e.int, i) }
got should === (expected)
}

{
implicit val iso = MonoidalTests.Isomorphisms.invariant[StateT[Option, Int, ?]]
checkAll("StateT[Option, Int, Int]", MonadStateTests[StateT[Option, Int, ?], Int].monadState[Int, Int, Int])
Expand Down

0 comments on commit 267721a

Please sign in to comment.