Skip to content

Instantly share code, notes, and snippets.

@notxcain
Last active August 28, 2018 10:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save notxcain/8593b8ed4ec4f0bad22f7c074fa4e764 to your computer and use it in GitHub Desktop.
Save notxcain/8593b8ed4ec4f0bad22f7c074fa4e764 to your computer and use it in GitHub Desktop.
// Tagless Encoding
trait Counter[F[_]] {
def increment(value: Int): F[Unit]
def decrement(value: Int): F[Unit]
def value: F[Int]
}
// Free Encoding
sealed abstract class CounterOp[A]
object CounterOp {
final case class Increment(value: Int) extends CounterOp[Unit]
final case class Decrement(value: Int) extends CounterOp[Unit]
final case object Value extends CounterOp[Int]
}
type CounterInvocation[A] = Invocation[Counter, A]
object CounterInvocations extends Counter[CounterInvocation] {
def increment(value: Int): CounterInvocation[Unit] = new CounterInvocation[Unit] {
def invoke[F[_]](counter: Counter[F]): F[Unit] = counter.increment
}
def decrement(value: Int): CounterInvocation[Unit] = new CounterInvocation[Unit] {
def invoke[F[_]](counter: Counter[F]): F[Unit] = counter.decrement
}
def value: CounterInvocation[Int] = new CounterInvocation[Int] {
def invoke[F[_]](counter: Counter[F]): F[Int] = counter.value
}
}
object CounterOps extends Counter[CounterOp] {
def increment(value: Int): CounterOp[Unit] = CounterOp.Increment(value)
def decrement(value: Int): CounterOp[Unit] = CounterOp.Decrement(value)
def value: CounterOp[Int] = CounterOp.Value
}
val proof = new IsoK[CounterOp, CounterInvocation] {
def from[A](co: CounterOp[A]): CounterInvocation[A] = co match {
case CounterOp.Increment(value) => CounterInvocations.increment(value)
case CounterOp.Decrement(value) => CounterInvocations.decrement(value)
case CounterOp.Value => CounterInvocations.value
}
def to[A](ci: CounterInvocation[A]): CounterOp[A] = ci.invoke(CounterOps)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment