Created
June 19, 2015 20:11
-
-
Save mpilquist/d8197ce896eb961d206b to your computer and use it in GitHub Desktop.
Example of summoning an HList of type class instances with Shapeless
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import shapeless._ | |
package object ex { | |
implicit class TypeClassHListOps[L <: HList](val self: L) extends AnyVal { | |
def summon[TC[_]](implicit op: HListTypeClassSummoner[TC, L]) = op.instance | |
} | |
trait HListTypeClassSummoner[TC[_], L <: HList] { | |
type Out <: HList | |
val instance: Out | |
} | |
object HListTypeClassSummoner { | |
type Aux[TC[_], L <: HList, O <: HList] = HListTypeClassSummoner[TC, L] { type Out = O } | |
implicit def forHNil[TC[_]]: Aux[TC, HNil, HNil] = new HListTypeClassSummoner[TC, HNil] { type Out = HNil; val instance = HNil } | |
implicit def forHCons[TC[_], H, T <: HList, TCT <: HList](implicit | |
tch: TC[H], | |
rest: HListTypeClassSummoner.Aux[TC, T, TCT] | |
): Aux[TC, H :: T, TC[H] :: TCT] = new HListTypeClassSummoner[TC, H :: T] { | |
type Out = TC[H] :: TCT | |
val instance = tch :: rest.instance | |
} | |
} | |
// Example | |
trait Semigroup[A] { def op(x: A, y: A): A } | |
implicit val sgInt = new Semigroup[Int] { def op(x: Int, y: Int) = x + y } | |
implicit val sgString = new Semigroup[String] { def op(x: String, y: String) = x + y } | |
implicit def sgList[A] = new Semigroup[List[A]] { def op(x: List[A], y: List[A]) = x ++ y } | |
val xs = 1 :: "Hello" :: List(1, 2, 3) :: HNil | |
val tc = xs.summon[Semigroup] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment