Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Created December 30, 2017 16:10
Show Gist options
  • Save yasuabe/f829e9ce02d9dcee17467da3a00928e9 to your computer and use it in GitHub Desktop.
Save yasuabe/f829e9ce02d9dcee17467da3a00928e9 to your computer and use it in GitHub Desktop.
arrow tutorial '6. a teaser'
import cats.Monoid
import cats.arrow.Arrow
import cats.data.Kleisli
sealed case class SimpleFunc[A, B](runF: A => B)
import cats.syntax.arrow._
import cats.syntax.compose._
def arr[F[_, _]: Arrow, A, B](f: A => B): F[A, B] = Arrow[F] lift f
def split[F[_, _]: Arrow, A]: F[A, (A, A)] = arr(x => (x, x))
def unsplit[F[_, _]: Arrow, A, B, C](f: (A, B) => C): F[(A, B), C] =
arr(f.tupled)
def liftA2[F[_, _], A, B, C, D](f: (B, C) => D, fb: F[A, B], fc: F[A, C])
(implicit A: Arrow[F]): F[A, D] =
(fb &&& fc) >>> unsplit(f)
// split[F, A] >>> A.first(fb) >>> A.second(fc) >>> unsplit(f)
// ArrowPlus ------------------
import cats.instances.list._
def returnA[S] = Arrow[Kleisli[List, ?, ?]].id[S]
implicit class ArrowPlus[X[_], S](k1: Kleisli[X, S, S])(implicit M: Monoid[X[S]]) {
def <+>(k2: Kleisli[X, S, S]) = Kleisli((s: S) => M.combine(k1.run(s), k2.run(s)))
}
type ListKleisli[A, B] = Kleisli[List, A, B]
def xform = {
val a = (f: String => String) => arr[ListKleisli, String, String](f)
def prepend(s: String) = a(s ++ _)
def append(s: String) = a(_ ++ s)
def withId(t: ListKleisli[String, String]) = returnA[String] <+> t
withId(prepend("<")) >>>
withId(append(">")) >>>
withId(prepend("!") >>> append("!"))
}
List("test", "foo").flatMap(xform.run)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment