Last active
December 28, 2015 19:59
-
-
Save tpolecat/7554206 to your computer and use it in GitHub Desktop.
Having a bit of a problem deriving implicit instances for product types.
This file contains 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._ | |
// typeclass for total number of fields (just an example) | |
class Width[A](val toInt: Int) | |
object Width { | |
// Get an instance | |
implicit def apply[A](implicit A: Width[A]) = A | |
// now derive for HList | |
implicit val fnil: Width[HNil] = | |
new Width[HNil](0) | |
implicit def fcons[H, T <: HList ](implicit H: Width[H], T: Width[T]): Width[H :: T] = | |
new Width[H :: T](H.toInt + T.toInt) | |
// and for products generally | |
implicit def fprod[P <: Product, L <: HList](implicit PL: Generic.Aux[P, L], L: Width[L]): Width[P] = | |
new Width[P](L.toInt) | |
} | |
// some instances | |
implicit val fooInt = new Width[Int](1) | |
implicit val fooStr = new Width[String](1) | |
Width[Int].toInt // 1 | |
Width[Int :: String :: HNil].toInt // 2 | |
Width[(Int, (String, String))].toInt // 3 | |
Width[(Int, ((String, Int), String))].toInt // 4 | |
// other products | |
case class Once(name: String) | |
case class Twice(f1: Once, f2: Once) // works as (Once, Int) for example | |
Width[Once].toInt // 1 | |
Width[Twice].toInt // 2 | |
Width[(Once, Int)].toInt // 2 | |
Width[(Twice, Int)].toInt | |
// <console>:25: error: diverging implicit expansion for type Width[(Twice, Int)] | |
// starting with method fprod in object Width | |
// Width[(Twice, Int)].toInt | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment