Skip to content

Instantly share code, notes, and snippets.

@missingfaktor
Created May 27, 2018 01:28
Show Gist options
  • Select an option

  • Save missingfaktor/9fb07e28346790a8cc8d1d57c1376cd8 to your computer and use it in GitHub Desktop.

Select an option

Save missingfaktor/9fb07e28346790a8cc8d1d57c1376cd8 to your computer and use it in GitHub Desktop.
object ShapelessMonoid {
import shapeless._
import shapeless.syntax._
import shapeless.ops.hlist.IsHCons
implicit def monoidHNil: Monoid[HNil] = new Monoid[HNil] {
def empty: HNil = HNil
def combine(x: HNil, y: HNil): HNil = HNil
}
implicit def monoidHCons[Head, Tail <: HList](
implicit
headMonoid: Monoid[Head],
tailMonoid: Monoid[Tail]
): Monoid[Head :: Tail] = {
new Monoid[Head :: Tail] {
def empty: Head :: Tail = {
headMonoid.empty :: tailMonoid.empty
}
def combine(x: Head :: Tail, y: Head :: Tail): Head :: Tail = {
x.head.combine(y.head) :: x.tail.combine(y.tail)
}
}
}
def deriveMonoid[A, Repr <: HList](
implicit
gen: Generic.Aux[A, Repr],
reprMonoid: Monoid[Repr]
) = {
new Monoid[A] {
def empty: A = {
gen.from(reprMonoid.empty)
}
def combine(x: A, y: A): A = {
gen.from(reprMonoid.combine(gen.to(x), gen.to(y)))
}
}
}
}
object MagnoliaMonoid {
type Typeclass[A] = Monoid[A]
def combine[A](caseClass: CaseClass[Monoid, A]): Monoid[A] = {
new Monoid[A] {
def empty: A = caseClass.construct { parameter =>
parameter.typeclass.empty
}
def combine(x: A, y: A): A = caseClass.construct { parameter =>
parameter.typeclass.combine(parameter.dereference(x), parameter.dereference(y))
}
}
}
def dispatch[A](sealedTrait: SealedTrait[Monoid, A]): Monoid[A] = {
throw new UnsupportedOperationException("Sum types not supported.")
}
def derive[A]: Monoid[A] = macro Magnolia.gen[A]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment