Skip to content

Commit

Permalink
Merge pull request #1769 from tpolecat/kleisli-tap
Browse files Browse the repository at this point in the history
Kleisli tap, tapWith
  • Loading branch information
tpolecat authored Jul 21, 2017
2 parents 16ea2ed + 11988af commit 0df2821
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
8 changes: 8 additions & 0 deletions core/src/main/scala/cats/data/Kleisli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ final case class Kleisli[F[_], A, B](run: A => F[B]) { self =>
def second[C](implicit F: Functor[F]): Kleisli[F, (C, A), (C, B)] =
Kleisli{ case (c, a) => F.map(run(a))(c -> _)}

/** Discard computed B and yield the input value. */
def tap(implicit F: Functor[F]): Kleisli[F, A, A] =
Kleisli(a => F.map(run(a))(_ => a))

/** Yield computed B combined with input value. */
def tapWith[C](f: (A, B) => C)(implicit F: Functor[F]): Kleisli[F, A, C] =
Kleisli(a => F.map(run(a))(b => f(a, b)))

def apply(a: A): F[B] = run(a)
}

Expand Down
14 changes: 13 additions & 1 deletion tests/src/test/scala/cats/tests/KleisliTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class KleisliTests extends CatsSuite {
checkAll("Kleisli[Option, Int, Int]", FunctorTests[Kleisli[Option, Int, ?]].functor[Int, Int, Int])
checkAll("Functor[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Functor[Kleisli[Option, Int, ?]]))
}

{
implicit val catsDataMonoidForKleisli = Kleisli.catsDataMonoidForKleisli[Option, Int, String]
checkAll("Kleisli[Option, Int, String]", GroupLaws[Kleisli[Option, Int, String]].monoid)
Expand Down Expand Up @@ -159,6 +159,18 @@ class KleisliTests extends CatsSuite {
}
}

test("tap") {
forAll { (f: Kleisli[List, Int, String], i: Int) =>
f.run(i).as(i) should === (f.tap.run(i))
}
}

test("tapWith") {
forAll { (f: Kleisli[List, Int, String], g: (Int, String) => Boolean, i: Int) =>
f.run(i).map(s => g(i, s)) should === (f.tapWith(g).run(i))
}
}

test("apply") {
forAll { (f: Kleisli[List, Int, Int], i: Int) =>
f.run(i) should === (f(i))
Expand Down

0 comments on commit 0df2821

Please sign in to comment.