Skip to content

Instantly share code, notes, and snippets.

@milessabin
Created February 25, 2012 11:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save milessabin/1907932 to your computer and use it in GitHub Desktop.
Save milessabin/1907932 to your computer and use it in GitHub Desktop.
Lifting Monoid over arbitrary arity type constructors
object MonoidExamples {
import shapeless._
import HList._
trait Monoid[T]
// Boilerplate ...
trait HListed[S, L <: HList]
implicit def hl1[S[_], A] = new HListed[S[A], A :: HNil] {}
implicit def hl2[S[_, _], A, B] = new HListed[S[A, B], A :: B :: HNil] {}
implicit def hl3[S[_, _, _], A, B, C] = new HListed[S[A, B, C], A :: B :: C :: HNil] {}
implicit def hl4[S[_, _, _, _], A, B, C, D] = new HListed[S[A, B, C, D], A :: B :: C :: D :: HNil] {}
implicit def hl5[S[_, _, _, _, _], A, B, C, D, Etc] = new HListed[S[A, B, C, D, Etc], A :: B :: C :: D :: Etc :: HNil] {}
// Rinse and repeat ...
// End of boilerplate.
trait Monoids[L <: HList]
implicit def hnilMonoids = new Monoids[HNil] {}
implicit def hlistMonoids[H, T <: HList](implicit mh : Monoid[H], mt : Monoids[T]) = new Monoids[H :: T] {}
implicit def hlistMonoid[S, L <: HList](implicit hl : HListed[S, L], ms : Monoids[L]) = new Monoid[S] {}
trait A
trait B
trait C
trait D
trait Etc
implicit def aMonoid = new Monoid[A] {}
implicit def bMonoid = new Monoid[B] {}
implicit def cMonoid = new Monoid[C] {}
implicit def dMonoid = new Monoid[D] {}
implicit def etcMonoid = new Monoid[Etc] {}
trait NotMonoid
//implicitly[Monoid[NotMonoid]]
trait TC1[A]
implicitly[Monoid[TC1[A]]]
//implicitly[Monoid[TC1[NotMonoid]]] // Doesn't compile
trait TC2[A, B]
implicitly[Monoid[TC2[A, B]]]
//implicitly[Monoid[TC2[A, NotMonoid]]] // Doesn't compile
trait TC3[A, B, C]
implicitly[Monoid[TC3[A, B, C]]]
//implicitly[Monoid[TC3[A, B, NotMonoid]]] // Doesn't compile
trait TC4[A, B, C, D]
implicitly[Monoid[TC4[A, B, C, D]]]
//implicitly[Monoid[TC4[A, B, C, NotMonoid]]] // Doesn't compile
trait TC5[A, B, C, D, E]
implicitly[Monoid[TC5[A, B, C, D, Etc]]]
//implicitly[Monoid[TC5[A, B, C, D, NotMonoid]]] // Doesn't compile
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment