Skip to content

Instantly share code, notes, and snippets.

@drdozer
Last active January 12, 2017 09:42
Show Gist options
  • Save drdozer/350935c4b1fd5b9e76b3be32cb96e112 to your computer and use it in GitHub Desktop.
Save drdozer/350935c4b1fd5b9e76b3be32cb96e112 to your computer and use it in GitHub Desktop.
// Sketches of various meta-encodings of monoids
// Naive typeclass trait
{
trait Monoid[M] {
def zero: M
def append(m1: M, m2: M): M
}
implicit object DoubleSumMonoid extends Monoid[Double] {
def zero = 1
def append(m1: Double, m2: Double) = m1 + m2
}
implict object DoubleProductMonoid extends Monoid[Double] {
def zero = 0
def append(m1: Double, m2: Double) = m1 * m2
}
}
// Typeclass trait with monoid selector
{
trait Monoid[M, S] {
def zero: M
def append(m1: M, m2: M): M
}
trait Sum
trait Product
implicit object DoubleSumMonoid extends Monoid[Double, Sum] {
def zero = 1
def append(m1: Double, m2: Double) = m1 + m2
}
implicit object DoubleProductMonoid extends Monoid[Double, Product] {
def zero = 0
def append(m1: Double, m2: Double) = m1 * m2
}
}
// Typeclass trait with typed lookup
{
trait InstanceAt[M, S] { def get: M }
trait Monoid[M] {
def zero: M
def append(m1: M, m2: M): M
}
object DoubleSumMonoid extends Monoid[Double] {
def zero = 1
def append(m1: Double, m2: Double) = m1 + m2
}
object DoubleProductMonoid extends Monoid[Double] {
def zero = 0
def append(m1: Double, m2: Double) = m1 * m2
}
trait Sum
trait Product
implicit val doubleSum = InstanceAt[Sum](DoubleSumMonoid)
implicit val doubleProduct = InstanceAt[Product](DoubleProductMonoid)
}
// Free Monoid, naive
{
sealed trait Rep[M]
case class Zero extends Rep[M]
case class Append(m1: Rep[M], m2: Rep[M])
}
// Free Monoid, selector
{
sealed trait Rep[M, S]
case class Zero extends Rep[M, S]
case class Append(m1: Rep[M, S], m2: Rep[M, S]) extends Rep[M, S]
}
// Tagless, naive
{
trait Monoidal[Rep[_], M] {
def zero: Rep[M]
def append(m1: Rep[M], m2: Rep[M]): Rep[M]
}
}
// Tagless, selector
{
trait Monoidal[Rep[_, _], M, S] {
def zero: Rep[M, S]
def append(m1: Rep[M, S], m2: Rep[M, S]): Rep[M, S]
}
}
// Tagless, naive, polymorphic
{
trait Monoidal[Rep[_]] {
def zero[M]: Rep[M]
def apend[M](m1: Rep[M], m2: Rep[M]): Rep[M]
}
}
// Tagless, selector, polymorphic
{
trait Monoidal[Rep[_, _]] {
def zero[M, S]: Rep[M, S]
def append[M, S](m1: Rep[M, S], m2: Rep[M, S]): Rep[M, S]
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment