Skip to content

Instantly share code, notes, and snippets.

@sgrif
Created March 27, 2015 17:21
Show Gist options
  • Select an option

  • Save sgrif/2f2bc5b8aae7063cc2f4 to your computer and use it in GitHub Desktop.

Select an option

Save sgrif/2f2bc5b8aae7063cc2f4 to your computer and use it in GitHub Desktop.
scalaVersion := "2.11.6"
libraryDependencies ++= Seq(
"com.chuusai" %% "shapeless" % "2.1.0"
)
import shapeless._
// Shitty stand in for complex Android OS class
class Parcel {
def writeInt(i: Int) {}
def readInt = 1
}
trait Parceler[A] {
def read(parcel: Parcel): A
def write(parcel: Parcel, value: A): Unit
}
object Parceler extends ProductTypeClassCompanion[Parceler] {
object typeClass extends ProductTypeClass[Parceler] {
def emptyProduct = new Parceler[HNil]{
def write(parcel: Parcel, a: HNil) = ()
def read(parcel: Parcel) = HNil
}
def product[F, T <: HList](FHead: Parceler[F], FTail: Parceler[T]) = new Parceler[F :: T] {
def write(parcel: Parcel, a: F :: T) {
FHead.write(parcel, a.head)
FTail.write(parcel, a.tail)
}
def read(parcel: Parcel) = {
FHead.read(parcel) :: FTail.read(parcel)
}
}
def project[F, G](instance: => Parceler[G], to: F => G, from: G => F) = new Parceler[F] {
def write(parcel: Parcel, a: F) = instance.write(parcel, to(a))
def read(parcel: Parcel) = from(instance.read(parcel))
}
}
implicit val intParceler = new Parceler[Int] {
def read(parcel: Parcel) = parcel.readInt
def write(parcel: Parcel, value: Int) = parcel.writeInt(value)
}
}
trait ParcelingInterface[T] { self: T =>
def parceler: Parceler[T]
def methodRequiringParceler {}
}
case class Foo(x: Int, y: Int) extends ParcelingInterface[Foo] {
// This line will fail to compile if you remove the explicit type annotation
val parceler: Parceler[Foo] = Parceler[Foo]
// This works as well
// val parceler: Parceler[Foo] = implicitly[Parceler[Foo]]
// these fail, but worked on 2.0
// val parceler = Parceler[Foo]
// val parceler = implicitly[Parceler[Foo]]
}
object Main extends App {
val parceler = implicitly[Parceler[Foo]]
// This fails in a similar fashion to the problem inside of Foo
// val listParceler = implicitly[Parceler[List[Int]]]
// This results in an infinite loop, fails to compile without the explicit type annotation
implicit def listParceler[A: Parceler]: Parceler[List[A]] = Parceler[List[A]]
val listP = implicitly[Parceler[List[Foo]]]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment