Skip to content

Instantly share code, notes, and snippets.

@davidhoyt
Last active January 25, 2016 05:41
Show Gist options
  • Save davidhoyt/5a759989122423d5674e to your computer and use it in GitHub Desktop.
Save davidhoyt/5a759989122423d5674e to your computer and use it in GitHub Desktop.
Combine 2 shapeless HLists of the same type using cats Semigroup
import shapeless._
import cats.std.all._
trait ShapelessCatsSemigroup {
implicit object HNilSemigroup extends Semigroup[HNil] {
override def combine(h1: HNil, h2: HNil): HNil = HNil
}
implicit def HListSemigroup[H : Semigroup, T <: HList : Semigroup]: Semigroup[H :: T] =
new Semigroup[H :: T] {
override def combine(hlist1: H :: T, hlist2: H :: T): H :: T = (hlist1, hlist2) match {
case (h1 :: t1, h2 :: t2) => Semigroup[H].combine(h1, h2) :: Semigroup[T].combine(t1, t2)
}
}
}
implicit class ShapelessCatsSemigroupOps[H <: HList](val h1: H) extends AnyVal {
def combine(h2: H)(implicit semigroup: Semigroup[H]): H = semigroup.combine(h1, h2)
}
object ShapelessCats
extends ShapelessCatsSemigroup
import ShapelessCats._
val h1: String :: Int :: HNil = "foo" :: 2 :: HNil
val h2: String :: Int :: HNil = "bar" :: 3 :: HNil
println(Semigroup[HNil].combine(HNil, HNil))
println(Semigroup[String :: Int :: HNil].combine(h1, h2))
println(h1.combine(h2))
// Output:
// HNil
// foobar :: 5 :: HNil
// foobar :: 5 :: HNil
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment