Skip to content

Commit

Permalink
Merge pull request #4406 from ivan-klass/Kleisli-localK
Browse files Browse the repository at this point in the history
Add `Kleisli.localK` `FunctionK` helper
  • Loading branch information
danicheg authored Mar 6, 2023
2 parents 0f18d6f + f76e012 commit 87473f7
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions core/src/main/scala/cats/data/Kleisli.scala
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,34 @@ object Kleisli
def applyK[F[_], A](a: A): Kleisli[F, A, *] ~> F =
new (Kleisli[F, A, *] ~> F) { def apply[B](k: Kleisli[F, A, B]): F[B] = k.apply(a) }

/**
* Creates a `FunctionK` that transforms a `Kleisli[F, A, B]` into an `Kleisli[F, C, B]` using `C => A`.
* {{{
* scala> import cats.{~>}, cats.data.Kleisli
*
* scala> def nonEmpty(s: String): Option[String] = Option(s).filter(_.nonEmpty)
* scala> type KOS[A] = Kleisli[Option, String, A]
* scala> type KOLS[A] = Kleisli[Option, List[String], A]
* scala> val size: KOS[Int] = Kleisli(s => nonEmpty(s).map(_.size))
* scala> val exclaim: KOS[String] = Kleisli(s => nonEmpty(s).map(nes => s"${nes.toUpperCase}!"))
* scala> size("boo")
* res0: Option[Int] = Some(3)
*
* scala> exclaim("boo")
* res1: Option[String] = Some(BOO!)
*
* scala> val mkStringK: KOS ~> KOLS = Kleisli.localK(_.mkString)
* scala> mkStringK(size)(List("foo", "bar", "baz"))
* res2: Option[Int] = Some(9)
*
* scala> mkStringK(exclaim)(List("foo", "bar", "baz"))
* res3: Option[String] = Some(FOOBARBAZ!)
* }}}
*/
def localK[F[_], A, C](f: C => A): Kleisli[F, A, *] ~> Kleisli[F, C, *] =
new (Kleisli[F, A, *] ~> Kleisli[F, C, *]) {
def apply[B](k: Kleisli[F, A, B]): Kleisli[F, C, B] = k.local(f)
}
}

sealed private[data] trait KleisliFunctions {
Expand Down

0 comments on commit 87473f7

Please sign in to comment.