Skip to content

Instantly share code, notes, and snippets.

@Krever
Created January 4, 2019 07:53
Show Gist options
  • Save Krever/271282ae0cddaed019fc6eec99cc7455 to your computer and use it in GitHub Desktop.
Save Krever/271282ae0cddaed019fc6eec99cc7455 to your computer and use it in GitHub Desktop.
import magnolia._
object MagnoliaTest {
trait TCA[T] {
def showA: String
}
trait TCB[T] {
def showB: String
}
trait Wrapper[T] {
type TC[X]
val tc: TC[T]
}
object Wrapper {
type Aux[T, _TC[_]] = Wrapper[T] { type TC[X] = _TC[X] }
trait ByTC[_TC[_]] {
type Out[T] = Wrapper[T] { type TC[X] = _TC[X] }
}
}
implicit def wrapTCA[T](implicit _tc: TCA[T]): Wrapper[T] = new Wrapper[T] {
override type TC[X] = TCA[X]
override val tc: TCA[T] = _tc
}
object Derivation {
type Typeclass[T] = Wrapper[T]
def combine[T](caseClass: CaseClass[Wrapper, T]): Wrapper.ByTC[TCB]#Out[T] = new Wrapper[T] {
override type TC[X] = TCB[X]
override val tc: TCB[T] = new TCB[T] {
override def showB: String = {
caseClass.parameters.map(p => s"${p.label}=${p.typeclass.tc.asInstanceOf[TCA[T]].showA}").mkString(", ")
}
}
}
def dispatch[T](sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T] = ???
def gen[T]: Typeclass[T] = macro Magnolia.gen[T]
}
def main(args: Array[String]): Unit = {
implicit val tcaString: TCA[String] = new TCA[String] { override def showA: String = "str" }
implicit val tcaInt: TCA[Int] = new TCA[Int] { override def showA: String = "int" }
tcaInt.toString // false positive non-used
implicitly[Wrapper[String]]
case class Foo(a: String, b: Int, c: String)
val derived = Derivation.gen[Foo].tc.asInstanceOf[TCB[Foo]]
println(derived.showB)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment