Skip to content

Instantly share code, notes, and snippets.

@yasuabe
Created December 30, 2017 15:59
Show Gist options
  • Save yasuabe/b67537e5e426d31a35eba8a46b54f77d to your computer and use it in GitHub Desktop.
Save yasuabe/b67537e5e426d31a35eba8a46b54f77d to your computer and use it in GitHub Desktop.
arrow tutorial '3. some arrow operations'
import cats.arrow.Arrow
sealed case class SimpleFunc[A, B](runF: A => B)
trait SimpleFuncInstances {
implicit val simpleFuncArrow: Arrow[SimpleFunc] = new Arrow[SimpleFunc] {
def lift[A, B](f: A => B): SimpleFunc[A, B] = SimpleFunc(f)
def first[A, B, C](fa: SimpleFunc[A, B]): SimpleFunc[(A, C), (B, C)] =
SimpleFunc { case (a, c) => (fa runF a , c) }
def compose[A, B, C](g: SimpleFunc[B, C], f: SimpleFunc[A, B]): SimpleFunc[A, C] =
SimpleFunc { g.runF compose f.runF }
}
}
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_2[F[_, _]: Arrow, A, B, C, D](f: (B, C) => D, fb: F[A, B], fc: F[A, C])
: F[A, D] = (fb &&& fc) >>> unsplit(f)
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] =
split[F, A] >>> A.first(fb) >>> A.second(fc) >>> unsplit(f)
object testArrow1 extends SimpleFuncInstances {
val f: SimpleFunc[Int, Int] = arr(_ / 2)
val g: SimpleFunc[Int, Int] = arr(_ * 3 + 1)
val h: (Int, Int) => Int = _ + _
def apply(n: Int) = liftA2(h, f, g).runF(n)
}
testArrow1(8)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment