Skip to content

Commit

Permalink
Merge pull request #1169 from zainab-ali/state
Browse files Browse the repository at this point in the history
Adding lift and inspect to StateT
  • Loading branch information
kailuowang authored Jul 13, 2016
2 parents 0d36ff3 + 90a2280 commit fe361a3
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
15 changes: 15 additions & 0 deletions core/src/main/scala/cats/data/StateT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,21 @@ object StateT extends StateTInstances {

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

def lift[F[_], S, A](fa: F[A])(implicit F: Applicative[F]): StateT[F, S, A] =
StateT(s => F.map(fa)(a => (s, a)))

def inspect[F[_], S, A](f: S => A)(implicit F: Applicative[F]): StateT[F, S, A] =
StateT(s => F.pure((s, f(s))))

def inspectF[F[_], S, A](f: S => F[A])(implicit F: Applicative[F]): StateT[F, S, A] =
StateT(s => F.map(f(s))(a => (s, a)))

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

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

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

test("State.inspect and StateT.inspect are consistent") {
forAll { (s: String, f: String => Int) =>
val state: State[String, Int] = State.inspect(f)
val stateT: State[String, Int] = StateT.inspect(f)
state.run(s) should === (stateT.run(s))
}
}

test("State.inspect and StateT.inspectF are consistent") {
forAll { (s: String, f: String => Int) =>
val state: State[String, Int] = State.inspect(f)
val stateT: State[String, Int] = StateT.inspectF(f.andThen(Eval.now))
state.run(s) should === (stateT.run(s))
}
}

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

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

test("State.pure and StateT.lift are consistent") {
forAll { (s: String, i: Int) =>
val state: State[String, Int] = State.pure(i)
val stateT: State[String, Int] = StateT.lift(Eval.now(i))
state.run(s) should === (stateT.run(s))
}
}

test("Cartesian syntax is usable on State") {
val x = add1 *> add1
x.runS(0).value should === (2)
Expand Down

0 comments on commit fe361a3

Please sign in to comment.