Created
March 27, 2015 17:21
-
-
Save sgrif/2f2bc5b8aae7063cc2f4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| scalaVersion := "2.11.6" | |
| libraryDependencies ++= Seq( | |
| "com.chuusai" %% "shapeless" % "2.1.0" | |
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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