Skip to content

Instantly share code, notes, and snippets.

@mrdziuban
Created May 18, 2018 15:51
Show Gist options
  • Save mrdziuban/91285606184c89b858fe92c7ebefa2c9 to your computer and use it in GitHub Desktop.
Save mrdziuban/91285606184c89b858fe92c7ebefa2c9 to your computer and use it in GitHub Desktop.
CSV type class derivation using magnolia
import magnolia.{CaseClass, Magnolia, SealedTrait}
import scala.language.experimental.macros
trait Csv[A] { def apply(a: A): Seq[String] }
trait LPCsv {
type Typeclass[A] = Csv[A]
def combine[A](ctx: CaseClass[Csv, A]): Csv[A] =
a => ctx.parameters.foldLeft(List[String]())((acc, p) => acc ++ p.typeclass(p.dereference(a)))
def dispatch[A](ctx: SealedTrait[Csv, A]): Csv[A] =
a => ctx.dispatch(a)(sub => sub.typeclass(sub.cast(a)))
implicit def deriveCsv[A]: Csv[A] = macro Magnolia.gen[A]
}
object csv extends LPCsv {
implicit val csvStr: Csv[String] = Seq(_)
implicit def csvSeq[A](implicit ca: Csv[A]): Csv[Seq[A]] = _.flatMap(ca(_))
}
case class Foo(s: String)
case class TypeParam[A](a: A)
case class Wrapper(tp: TypeParam[Foo])
import csv._
implicitly[Csv[Seq[Wrapper]]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment