// in bijection branch jco/macro_case_class_plus // ./sbt "bijection-macros/console" // paste the following // Use :paste until the break below. :paste import com.twitter.bijection._ import com.twitter.bijection.macros.common.TypesNotEqual trait Semigroup[T] { def plus(left: T, right: T): T } implicit val intSemigroup: Semigroup[Int] = new Semigroup[Int] { override def plus(left: Int, right: Int) = left + right } case class Wrapper(get: Int) extends AnyVal implicit val intWrapperBij: Bijection[Int, Wrapper] = Bijection.build[Int, Wrapper] { Wrapper(_) } { _.get } trait TypeclassBijection[T[_]] { def apply[A, B](tc: T[A], bij: Bijection[A, B]): T[B] } implicit val semigroupTypeclassBijection: TypeclassBijection[Semigroup] = new TypeclassBijection[Semigroup] { def apply[A, B](tc: Semigroup[A], bij: Bijection[A, B]) = new Semigroup[B] { override def plus(left: B, right: B) = bij(tc.plus(bij.invert(left), bij.invert(right))) } } // Now hit Ctrl-D and paste the rest. import com.twitter.bijection.macros.common.MacroImplicits._ implicit def typeclassBijection[T[_], A, B](implicit tcBij: TypeclassBijection[T], typeclass: T[A], notEqual: TypesNotEqual[A, B], bij: ImplicitBijection[A, B]): T[B] = tcBij(typeclass, bij.bijection) implicitly[Semigroup[Wrapper]]