Skip to content

Instantly share code, notes, and snippets.

@milessabin
Created September 25, 2013 23:14
Show Gist options
  • Save milessabin/6707525 to your computer and use it in GitHub Desktop.
Save milessabin/6707525 to your computer and use it in GitHub Desktop.
New in shapeless 2.0.0-SNAPSHOT (post M1): lazy recursive implicit values ... normally you would expect the recursion between List[T] and Cons[T] to cause the implicit resolution for Show[T] to blow up with a diverging implicit expansion.
import shapeless._
sealed trait List[+T]
case class Cons[T](hd: T, tl: List[T]) extends List[T]
sealed trait Nil extends List[Nothing]
case object Nil extends Nil
trait Show[T] {
def apply(t: T): String
}
def show[T](t: T)(implicit s: Show[T]) = s(t)
implicit def showInt: Show[Int] = new Show[Int] {
def apply(t: Int) = t.toString
}
implicit def showNil: Show[Nil] = new Show[Nil] {
def apply(t: Nil) = "Nil"
}
implicit def showCons[T](implicit st: Lazy[Show[T]], sl: Lazy[Show[List[T]]]): Show[Cons[T]] = new Show[Cons[T]] {
def apply(t: Cons[T]) = s"Cons(${show(t.hd)(st.value)}, ${show(t.tl)(sl.value)})"
}
implicit def showList[T](implicit sc: Lazy[Show[Cons[T]]]): Show[List[T]] = new Show[List[T]] {
def apply(t: List[T]) = t match {
case n: Nil => show(n)
case c: Cons[T] => show(c)(sc.value)
}
}
scala> val l: List[Int] = Cons(1, Cons(2, Cons(3, Nil)))
l: List[Int] = Cons(1,Cons(2,Cons(3,Nil)))
scala> show(l)
res0: String = Cons(1, Cons(2, Cons(3, Nil)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment