Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- trait Semigroup[A] { def combine(a: A, b: A): A }
- object Semigroup { def apply[A](a: A, b: A)(implicit ev: Semigroup[A]): A = ev.combine(a, b) }
- implicit object StrSemi extends Semigroup[String] { def combine(a: String, b: String): String = a + b }
- implicit def SemiTuple2[A, B](implicit ev1: Semigroup[A], ev2: Semigroup[B]): Semigroup[(A, B)] = new Semigroup[(A, B)] {
- def combine(a: (A, B), b: (A, B)): (A, B) = (ev1.combine(a._1, b._1), ev2.combine(a._2, b._2))
- }
- def buildInstance(size: Int) = {
- val instanceName = Term.Name(s"SemiTuple${size}")
- val (tparms, types) = (1 to size).toList.map({ i =>
- val tname = Type.Name(s"A${i}")
- (tparam"${tname}", tname)
- }).unzip
- val evs: List[Term.Param] = (1 to size).toList.map({ i =>
- val ev = param"implicit ${Term.Name(s"ev${i}")}: Semigroup[${Type.Name(s"A${i}")}]"
- // val access = { elem: Term => q"${elem}.${Term.Name(s"_${i}")}" }
- ev
- })
- q"""
- implicit def ${instanceName}[..${tparms}](..${evs}) = new Semigroup[(..${types})] {
- def combine(a: (..${types}), b: (..${types})): (..${types}) = (..${(1 to size).toList.map({ i => q"${Term.Name(s"ev${i}")}.combine(a.${Term.Name(s"_${i}")}, b.${Term.Name(s"_${i}")})" })})
- }
- """
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement