diff --git a/util/collection/KList.scala b/util/collection/KList.scala index 7b58aca32..5c0952cf1 100644 --- a/util/collection/KList.scala +++ b/util/collection/KList.scala @@ -13,7 +13,7 @@ import Types._ * For background, see * http://apocalisp.wordpress.com/2010/11/01/type-level-programming-in-scala-part-8a-klist%C2%A0motivation/ */ -sealed trait KList[+M[_], HL <: HList] +sealed trait KList[M[_], HL <: HList] { type Raw = HL /** Transform to the underlying HList type.*/ @@ -33,12 +33,12 @@ trait KFold[M[_],P[_ <: HList]] def knil: P[HNil] } -final case class KCons[H, T <: HList, +M[_]](head: M[H], tail: KList[M,T]) extends KList[M, H :+: T] +final case class KCons[H, T <: HList, M[_]](head: M[H], tail: KList[M,T]) extends KList[M, H :+: T] { def down(implicit f: M ~> Id) = HCons(f(head), tail down f) def transform[N[_]](f: M ~> N) = KCons( f(head), tail transform f ) // prepend - def :^: [N[X] >: M[X], G](g: N[G]) = KCons(g, this) + def :^: [G](g: M[G]) = KCons(g, this) def toList = head :: tail.toList def combine[N[X] >: M[X]]: (H :+: T)#Wrap[N] = HCons(head, tail.combine) @@ -48,29 +48,31 @@ final case class KCons[H, T <: HList, +M[_]](head: M[H], tail: KList[M,T]) exten def foldr[P[_ <: HList],N[X] >: M[X]](f: KFold[N,P]) = f.kcons(head, tail foldr f) } -sealed class KNil extends KList[Nothing, HNil] +sealed case class KNil[M[_]]() extends KList[M, HNil] { - def down(implicit f: Nothing ~> Id) = HNil - def transform[N[_]](f: Nothing ~> N) = KNil - def :^: [M[_], H](h: M[H]) = KCons(h, this) + def down(implicit f: M ~> Id) = HNil + def transform[N[_]](f: M ~> N) = new KNil[N] def toList = Nil def combine[N[X]] = HNil override def foldr[P[_ <: HList],N[_]](f: KFold[N,P]) = f.knil override def toString = "KNil" } -object KNil extends KNil - +object KNil +{ + def :^: [M[_], H](h: M[H]) = KCons(h, new KNil[M]) +} object KList { + implicit def convert[M[_]](k: KNil.type): KNil[M] = KNil() // nicer alias for pattern matching val :^: = KCons - def fromList[M[_]](s: Seq[M[_]]): KList[M, _ <: HList] = if(s.isEmpty) KNil else KCons(s.head, fromList(s.tail)) + def fromList[M[_]](s: Seq[M[_]]): KList[M, _ <: HList] = if(s.isEmpty) KNil() else KCons(s.head, fromList(s.tail)) // haven't found a way to convince scalac that KList[M, H :+: T] implies KCons[H,T,M] // Therefore, this method exists to put the cast in one location. implicit def kcons[H, T <: HList, M[_]](kl: KList[M, H :+: T]): KCons[H,T,M] = kl.asInstanceOf[KCons[H,T,M]] // haven't need this, but for symmetry with kcons: - implicit def knil[M[_]](kl: KList[M, HNil]): KNil = KNil + implicit def knil[M[_]](kl: KList[M, HNil]): KNil[M] = KNil() } diff --git a/util/collection/Types.scala b/util/collection/Types.scala index 42b81f990..3a4be2c11 100644 --- a/util/collection/Types.scala +++ b/util/collection/Types.scala @@ -7,7 +7,7 @@ object Types extends Types { implicit def hconsToK[M[_], H, T <: HList](h: M[H] :+: T)(implicit mt: T => KList[M, T]): KList[M, H :+: T] = KCons[H, T, M](h.head, mt(h.tail) ) - implicit def hnilToK(hnil: HNil): KNil = KNil + implicit def hnilToK[M[_]](hnil: HNil): KNil[M] = KNil() } trait Types extends TypeFunctions