Skip to content

Instantly share code, notes, and snippets.

@Leammas
Created February 16, 2017 07:48
Show Gist options
  • Save Leammas/84d9f6c4fb8bd44155aa64d02f11cde7 to your computer and use it in GitHub Desktop.
Save Leammas/84d9f6c4fb8bd44155aa64d02f11cde7 to your computer and use it in GitHub Desktop.
import cats.{Id, Monad}
import cats.free.Free
import io.aecor.liberator.{FreeAlgebra, ProductKK}
import io.aecor.liberator.macros.free
import cats.implicits._
object Main extends App {
case class Foo(id: Int, content: String)
@free
trait CrudActions[F[_]] {
def create(a: Foo): F[Int]
def read(id: Int): F[Foo]
def update(a: Foo): F[Unit]
def delete(id: Int): F[Unit]
}
@free
trait SumActions[F[_]] {
def concat(a: Foo, b: Foo): F[Foo]
def sum(a: Foo, b: Foo): F[Foo]
}
def program[F[_] : Monad : CrudActions : SumActions] : (Foo) => F[List[Foo]] = f => {
for {
id <- CrudActions[F].create(f)
created <- CrudActions[F].read(id)
_ <- CrudActions[F].update(created.copy(content = "bar"))
updated <- CrudActions[F].read(id)
concated <- SumActions[F].concat(created, updated)
summed <- SumActions[F].sum(created, updated)
} yield List(concated, summed)
}
val freeAlgebra = FreeAlgebra[ProductKK[CrudActions, SumActions, ?[_]]]
val freeProg = program[Free[freeAlgebra.Out, ?]]
val idCrud = new CrudActions[Id] {
var store = Map.empty[Int, Foo]
var ai = 1
def create(a: Foo): Id[Int] = {
val aId = a.copy(id = ai)
store = store + (ai -> aId)
ai = ai + 1
aId.id
}
def read(id: Int): Id[Foo] = store(id)
def update(a: Foo): Id[Unit] = {
store = store.updated(a.id, a)
()
}
def delete(id: Int): Id[Unit] = {
store = store - id
()
}
}
val idSum = new SumActions[Id] {
def concat(a: Foo, b: Foo): Id[Foo] = Foo(a.id, a.content + b.content)
def sum(a: Foo, b: Foo): Id[Foo] = Foo(a.id + b.id, a.content)
}
val toRun = freeProg(Foo(-100, "content"))
assert {
toRun.foldMap(freeAlgebra(ProductKK(idCrud, idSum))) == List(Foo(1, "contentbar"), Foo(2, "content"))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment