Skip to content

Instantly share code, notes, and snippets.

@alexarchambault
Last active August 29, 2015 14:13
Show Gist options
  • Save alexarchambault/e447943272bd5c0ae9b8 to your computer and use it in GitHub Desktop.
Save alexarchambault/e447943272bd5c0ae9b8 to your computer and use it in GitHub Desktop.
Lazy & generics
scalaVersion := "2.11.5"
resolvers ++= Seq(
Resolver.sonatypeRepo("releases"),
Resolver.sonatypeRepo("snapshots")
)
libraryDependencies ++= Seq(
"com.chuusai" %% "shapeless" % "2.1.0-SNAPSHOT"
)
package gen
import shapeless._, record._, labelled._
trait TC[T]
object TC {
def apply[T](implicit tc: TC[T]): TC[T] = tc
implicit val booleanTC: TC[Boolean] = new TC[Boolean] {}
implicit val hnilTC: TC[HNil] = new TC[HNil] {}
implicit def hconsTC[H, T <: HList](implicit
headTC: Lazy[TC[H]],
tailTC: Lazy[TC[T]]
): TC[H :: T] =
new TC[H :: T] {}
implicit def instanceTC[F, G](implicit
lgen: Generic.Aux[F, G],
tc: Lazy[TC[G]]
): TC[F] =
new TC[F] {}
}
object Issue {
case class Wrapper[T](flag: Boolean, underlying: T)
case class Test(b: Boolean)
def specific(): Unit = {
TC[Test]
TC[HList.` `.T]
TC[HList.`Test`.T]
implicitly[Lazy[TC[Test]]]
implicitly[Lazy[TC[HList.` `.T]]]
implicitly[Lazy[TC[HList.`Test`.T]]] // Compiles
()
}
def generic[T: TC](): Unit = {
TC[T]
TC[HList.` `.T]
TC[HList.`T`.T]
implicitly[Lazy[TC[T]]]
implicitly[Lazy[TC[HList.` `.T]]]
implicitly[Lazy[TC[HList.`T`.T]]] // This one gives [error] (compile:compile) scala.tools.nsc.typechecker.Infer$NoInstance: undetermined type
// Goal here is to have
// TC[Wrapper[T]]
()
}
}
package lgen
import shapeless._, record._, labelled._
trait TC[T]
object TC {
def apply[T](implicit tc: TC[T]): TC[T] = tc
implicit val booleanTC: TC[Boolean] = new TC[Boolean] {}
implicit val hnilTC: TC[HNil] = new TC[HNil] {}
implicit def hconsTC[K <: Symbol, H, T <: HList](implicit
key: Witness.Aux[K],
headTC: Lazy[TC[H]],
tailTC: Lazy[TC[T]]
): TC[FieldType[K, H] :: T] =
new TC[FieldType[K, H] :: T] {}
implicit def instanceTC[F, G](implicit
lgen: LabelledGeneric.Aux[F, G],
tc: Lazy[TC[G]]
): TC[F] =
new TC[F] {}
}
object Issue {
case class Wrapper[T](flag: Boolean, underlying: T)
case class Test(b: Boolean)
def specific(): Unit = {
TC[Test]
TC[Record.` `.T]
TC[Record.`'underlying -> Test`.T]
implicitly[Lazy[TC[Test]]]
implicitly[Lazy[TC[Record.` `.T]]]
implicitly[Lazy[TC[Record.`'underlying -> Test`.T]]] // Found
()
}
def generic[T: TC](): Unit = {
TC[T]
TC[Record.` `.T]
TC[Record.`'underlying -> T`.T]
implicitly[Lazy[TC[T]]]
implicitly[Lazy[TC[Record.` `.T]]]
implicitly[Lazy[TC[Record.`'underlying -> T`.T]]] // Not found
// Goal here is to have
// TC[Wrapper[T]]
()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment