Created
February 3, 2017 10:50
-
-
Save Leammas/208f7f9d4e21cbaea6772275844b75c7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cats.data.Coproduct | |
import cats.free.{Free, Inject} | |
import cats.{Id, ~>} | |
object another extends App { | |
sealed trait CRUD[A] | |
case class Create(a: Foo) extends CRUD[Int] | |
case class Read(id: Int) extends CRUD[Foo] | |
case class Update(a: Foo) extends CRUD[Unit] | |
case class Delete(id: Int) extends CRUD[Unit] | |
case class Foo(id: Int, content: String) | |
class CrudActions[F[_]](implicit I: Inject[CRUD, F]) { | |
def create(a: Foo) = Free.inject[CRUD, F](Create(a)) | |
def read(id: Int) = Free.inject[CRUD, F](Read(id)) | |
def update(a: Foo) = Free.inject[CRUD, F](Update(a)) | |
def delete(id: Int) = Free.inject[CRUD, F](Delete(id)) | |
} | |
object CrudActions { | |
implicit def crud[F[_]](implicit I: Inject[CRUD, F]): CrudActions[F] = new CrudActions[F] | |
} | |
sealed trait Sum[A] | |
case class ConcatFoo(a: Foo, b: Foo) extends Sum[Foo] | |
case class SumFoo(a: Foo, b: Foo) extends Sum[Foo] | |
class SumActions[F[_]](implicit I: Inject[Sum, F]) { | |
def concat(a: Foo, b: Foo) = Free.inject[Sum, F](ConcatFoo(a, b)) | |
def sum(a: Foo, b: Foo) = Free.inject[Sum, F](SumFoo(a, b)) | |
} | |
object SumActions { | |
implicit def suma[F[_]](implicit I: Inject[Sum, F]): SumActions[F] = new SumActions[F] | |
} | |
type FooApp[A] = Coproduct[CRUD, Sum, A] | |
def program(implicit cp: CrudActions[FooApp], sp: SumActions[FooApp]): (Foo) => Free[FooApp, List[Foo]] = f => { | |
import cp._ | |
import sp._ | |
for { | |
id <- create(f) | |
created <- read(id) | |
_ <- update(created.copy(content = "bar")) | |
updated <- read(id) | |
concated <- concat(created, updated) | |
summed <- sum(created, updated) | |
} yield List(concated, summed) | |
} | |
object InterpreterId extends (CRUD ~> Id) { | |
var store = Map.empty[Int, Foo] | |
var ai = 1 | |
def apply[A](fa: CRUD[A]): Id[A] = fa match { | |
case Create(a) => | |
val aId = a.copy(id = ai) | |
store = store + (ai -> aId) | |
ai = ai + 1 | |
aId.id | |
case Read(id) => | |
store(id) | |
case Update(a) => | |
store = store.updated(a.id, a) | |
() | |
case Delete(id) => | |
store = store - id | |
() | |
} | |
} | |
object ISumId extends (Sum ~> Id) { | |
def apply[A](fa: Sum[A]): Id[A] = fa match { | |
case ConcatFoo(a, b) => Foo(a.id, a.content + b.content) | |
case SumFoo(a, b) => Foo(a.id + b.id, a.content) | |
} | |
} | |
val interpreter: FooApp ~> Id = InterpreterId or ISumId | |
val toRun = program(CrudActions.crud, SumActions.suma)(Foo(-100, "content")) | |
assert { | |
toRun.foldMap(interpreter) == 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