Guest User

Untitled

a guest
Sep 15th, 2019
84
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. trait Semigroup[A] { def combine(a: A, b: A): A }
  2. object Semigroup { def apply[A](a: A, b: A)(implicit ev: Semigroup[A]): A = ev.combine(a, b) }
  3. implicit object StrSemi extends Semigroup[String] { def combine(a: String, b: String): String = a + b }
  4. implicit def SemiTuple2[A, B](implicit ev1: Semigroup[A], ev2: Semigroup[B]): Semigroup[(A, B)] = new Semigroup[(A, B)] {
  5. def combine(a: (A, B), b: (A, B)): (A, B) = (ev1.combine(a._1, b._1), ev2.combine(a._2, b._2))
  6. }
  7. def buildInstance(size: Int) = {
  8. val instanceName = Term.Name(s"SemiTuple${size}")
  9. val (tparms, types) = (1 to size).toList.map({ i =>
  10. val tname = Type.Name(s"A${i}")
  11. (tparam"${tname}", tname)
  12. }).unzip
  13. val evs: List[Term.Param] = (1 to size).toList.map({ i =>
  14. val ev = param"implicit ${Term.Name(s"ev${i}")}: Semigroup[${Type.Name(s"A${i}")}]"
  15. // val access = { elem: Term => q"${elem}.${Term.Name(s"_${i}")}" }
  16. ev
  17. })
  18. q"""
  19. implicit def ${instanceName}[..${tparms}](..${evs}) = new Semigroup[(..${types})] {
  20. 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}")})" })})
  21. }
  22. """
  23. }
RAW Paste Data