Skip to content

Instantly share code, notes, and snippets.

@davegurnell
Created August 30, 2016 18:43
Show Gist options
  • Select an option

  • Save davegurnell/4722716e488412851633b32e7dbd7e07 to your computer and use it in GitHub Desktop.

Select an option

Save davegurnell/4722716e488412851633b32e7dbd7e07 to your computer and use it in GitHub Desktop.
shapeless lazy example
import shapeless._
trait CsvEncoder[A] {
def encode(value: A): List[String]
}
object CsvEncoder {
def apply[A](implicit encoder: CsvEncoder[A]): CsvEncoder[A] =
encoder
def pure[A](func: A => List[String]): CsvEncoder[A] =
new CsvEncoder[A] {
def encode(value: A): List[String] = func(value)
}
}
implicit val intEncoder: CsvEncoder[Int] =
CsvEncoder.pure(num => List(num.toString))
implicit val hnilEncoder: CsvEncoder[HNil] =
CsvEncoder.pure(hnil => Nil)
implicit def hlistEncoder[H, T <: HList](
implicit
hEncoder: Lazy[CsvEncoder[H]],
tEncoder: CsvEncoder[T]
): CsvEncoder[H :: T] =
CsvEncoder.pure(pair => hEncoder.value.encode(pair.head) ++ tEncoder.encode(pair.tail))
implicit val cnilEncoder: CsvEncoder[CNil] =
CsvEncoder.pure(cnil => ???)
implicit def coproductEncoder[H, T <: Coproduct](
implicit
hEncoder: Lazy[CsvEncoder[H]],
tEncoder: CsvEncoder[T]
): CsvEncoder[H :+: T] =
CsvEncoder.pure {
case Inl(h) => hEncoder.value.encode(h)
case Inr(t) => tEncoder.encode(t)
}
implicit def genericEncoder[A, R](
implicit
gen: Generic.Aux[A, R],
rEncoder: Lazy[CsvEncoder[R]]
): CsvEncoder[A] =
CsvEncoder.pure(value => rEncoder.value.encode(gen.to(value)))
sealed trait Tree[A]
final case class Branch[A](left: Tree[A], right: Tree[A]) extends Tree[A]
final case class Leaf[A](value: A) extends Tree[A]
implicitly[CsvEncoder[Tree[Int]]]
@davegurnell
Copy link
Author

I am confused!

If I paste this whole lot into the REPL, it fails to find an instance for CsvEncoder.

If I paste everything bar the last line, then paste the last line, it works fine.

If I run this code from the tut examples in shapeless-guide, it sends the compiler into an infinite loop. Probably because I'm redefining certain definitions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment