import com.github.dmytromitin.auxify.macros.{aux, instance}
/*@aux*/ @instance
trait Compare[T1, T2] {
type T
type Out = (T, T)
def apply(a: T1, b: T2): Out
}
object Compare {
type Aux[T1, T2, T0] = Compare[T1, T2] { type T = T0 }
// def instance[T1, T2, T0](f: (T1, T2) => (T0, T0)): Aux[T1, T2, T0] = new Compare[T1, T2] {
// override type T = T0
// override def apply(a: T1, b: T2): Out = f(a, b)
// }
implicit def reverseCompare[T1, T2](implicit ev: T2 => T1): Aux[T1, T2, T1] = instance((a, b) => (a, ev(b)))
implicit def directCompare[T1, T2](implicit ev: T1 => T2): Aux[T1, T2, T2] = instance((a, b) => (ev(a), b))
}
def compare[T1, T2](a: T1, b: T2)(implicit cmp: Compare[T1, T2]) = (compareImpl[cmp.T] _).tupled(cmp(a, b))
def compareImpl[T](a: T, b: T) = a == b
case class Foo(s: String)
case class Bar(s: String)
implicit def foo2bar(f: Foo): Bar = Bar(f.s)
compare(Foo("hello"), Bar("hello"))
Warning:scalac: {
abstract trait Compare[T1, T2] extends scala.AnyRef {
type T;
type Out = scala.Tuple2[T, T];
def apply(a: T1, b: T2): Out
};
object Compare extends scala.AnyRef {
def <init>() = {
super.<init>();
()
};
def instance[T1, T2, T0$macro$1](f$macro$2: _root_.scala.Function2[T1, T2, Out]): Compare[T1, T2] {
type T = T0$macro$1
} = {
final class $anon extends Compare[T1, T2] {
def <init>() = {
super.<init>();
()
};
override type T = T0$macro$1;
type Out = scala.Tuple2[T, T];
override def apply(a: T1, b: T2): Out = f$macro$2(a, b)
};
new $anon()
};
type Aux[T1, T2, T0] = Compare[T1, T2] {
type T = T0
};
implicit def reverseCompare[T1, T2](implicit ev: _root_.scala.Function1[T2, T1]): Aux[T1, T2, T1] = instance(((a, b) => scala.Tuple2(a, ev(b))));
implicit def directCompare[T1, T2](implicit ev: _root_.scala.Function1[T1, T2]): Aux[T1, T2, T2] = instance(((a, b) => scala.Tuple2(ev(a), b)))
};
()
}
Error:(11, 13) not found: type Out
/*@aux*/ @instance