Skip to content

Commit

Permalink
Merge pull request #1388 from tixxit/topic/statet-set
Browse files Browse the repository at this point in the history
Add StateT.set and StateT.setF.
  • Loading branch information
adelbertc authored Sep 22, 2016
2 parents 7f3b80c + 8653e22 commit dbda84c
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
6 changes: 6 additions & 0 deletions core/src/main/scala/cats/data/StateT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ object StateT extends StateTInstances {

def modifyF[F[_], S](f: S => F[S])(implicit F: Applicative[F]): StateT[F, S, Unit] =
StateT(s => F.map(f(s))(s => (s, ())))

def set[F[_], S](s: S)(implicit F: Applicative[F]): StateT[F, S, Unit] =
StateT(_ => F.pure((s, ())))

def setF[F[_], S](fs: F[S])(implicit F: Applicative[F]): StateT[F, S, Unit] =
StateT(_ => F.map(fs)(s => (s, ())))
}

private[data] sealed trait StateTInstances extends StateTInstances1 {
Expand Down
32 changes: 32 additions & 0 deletions tests/src/test/scala/cats/tests/StateTTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ class StateTTests extends CatsSuite {
}
}

test("State.set and StateT.set are consistent") {
forAll { (init: String, s: String) =>
val state: State[String, Unit] = State.set(s)
val stateT: StateT[Eval, String, Unit] = StateT.set(s)
state.run(init) should === (stateT.run(init))
}
}

test("State.set and StateT.setF are consistent") {
forAll { (init: String, s: String) =>
val state: State[String, Unit] = State.set(s)
val stateT: StateT[Eval, String, Unit] = StateT.setF(Eval.now(s))
state.run(init) should === (stateT.run(init))
}
}

test("Cartesian syntax is usable on State") {
val x = add1 *> add1
x.runS(0).value should === (2)
Expand Down Expand Up @@ -124,6 +140,22 @@ class StateTTests extends CatsSuite {
}
}

test("StateT.set equivalent to modify ignoring first param") {
forAll { (init: String, update: String) =>
val s1 = StateT.modify[Eval, String](_ => update)
val s2 = StateT.set[Eval, String](update)
s1.run(init) should === (s2.run(init))
}
}

test("StateT.setF equivalent to modifyF ignoring first param") {
forAll { (init: String, update: String) =>
val s1 = StateT.modifyF[Eval, String](_ => Eval.now(update))
val s2 = StateT.setF(Eval.now(update))
s1.run(init) should === (s2.run(init))
}
}

test(".get and then .run produces same state as value"){
forAll { (s: State[Long, Int], initial: Long) =>
val (finalS, finalA) = s.get.run(initial).value
Expand Down

0 comments on commit dbda84c

Please sign in to comment.