How to create Kleisli with Kleisli.local (not local for transforming)

100 views Asked by At

There are 2 local methods defined as:

final case class Kleisli[F[_], A, B](run: A => F[B]) { self =>
  ...
  def local[AA](f: AA => A): Kleisli[F, AA, B] =
    Kleisli(f.andThen(run))
  ...
}

and as:

sealed private[data] trait KleisliFunctions {
  ...
  def local[M[_], A, R](f: R => R)(fa: Kleisli[M, R, A]): Kleisli[M, R, A] =
    Kleisli(f.andThen(fa.run))
}

The 2nd one should be used as a factory method, to construct Kleisli.

Can you please offer any usecases to use the 2nd method, defined in KleisliFunctions, to create instance of Kleisli. With an example, if possible. Cannot get it, where this method could be useful.

2

There are 2 answers

0
Dmytro Mitin On BEST ANSWER

For example

val k: Kleisli[Option, String, Char] = Kleisli(_.headOption)

k.local[Int](_.toString): Kleisli[Option, Int, Char]  // Kleisli#local

Kleisli.local((_: String).toUpperCase)(k): Kleisli[Option, String, Char] // KleisliFunctions#local

Object Kleisli extends trait KleisliFunctions.

0
Alexey Romanov On

What I can note is: Kleisli.local(f)(fa) is the same as fa.local(f), but it's both more verbose and strictly less powerful (it requires argument and return type of f to be the same, fa.local(f) doesn't).

A potential reason to use it would be if fa's type needs to be inferred, in which case Kleisli.local provides an expected type and fa.local doesn't.