Skip to content

Instantly share code, notes, and snippets.

@timperrett
Created September 15, 2016 11:55
Show Gist options
  • Select an option

  • Save timperrett/7106803dd2e85689147c93ddef558ba2 to your computer and use it in GitHub Desktop.

Select an option

Save timperrett/7106803dd2e85689147c93ddef558ba2 to your computer and use it in GitHub Desktop.
Example of using CoProducts of Free algebras
package example
/*
* REQUIRES KIND PROJECTOR 0.9.0 (untested with any other version, but should be easily adaptable)
*/
import scalaz._, Scalaz._
sealed abstract class FooOp[A]
extends Product with Serializable
object FooOp {
final case class Foo1(i: Int) extends FooOp[String]
type FooF[A] = Free.FreeC[FooOp, A]
def gogogo(i: Int): FooF[String] = Free.liftFC[FooOp,String](Foo1(i))
}
sealed abstract class QuxOp[A]
extends Product with Serializable
object QuxOp {
final case class Qux1(i: Int) extends QuxOp[Int]
type QuxF[A] = Free.FreeC[QuxOp, A]
def gogogo(i: Int): QuxF[Int] = Free.liftFC[QuxOp,Int](Qux1(i))
}
import scalaz.concurrent.Task
object Comb {
type CombOp[A] = Coproduct[QuxOp, FooOp, A]
type CombF[A] = Free.FreeC[CombOp, A]
def injectFC[F[_], G[_]](implicit I: Inject[F, G]): FreeC[F, ?] ~> FreeC[G, ?] =
λ[FreeC[F, ?] ~> FreeC[G, ?]](_ mapSuspension λ[Coyoneda[F, ?] ~> Coyoneda[G, ?]](_.trans(I)))
final implicit class InjectCombF[F[_],A](val fa: Free.FreeC[F,A])(implicit I: Inject[F, Comb.CombOp]) {
def inject[G[_]] = injectFC.apply(fa)
}
def run[A](wf: CombF[A])(trans: CombOp ~> Task): Task[A] =
Free.runFC(wf)(trans)
def useQux(x: Int): CombF[Int] =
QuxOp.gogogo(x).inject
def useFoo(x: Int): CombF[String] =
FooOp.gogogo(x).inject
def xxx: CombF[String] = {
for {
a <- useQux(1)
b <- useFoo(a)
} yield b
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment