mirror of https://github.com/sbt/sbt.git
KList updates
- exchange variance annotations on KList for a bounded existential in KList.toList - add foldr (reason for dropping variance annotations) - add functions stating equivalence between + KList[M,H :+: T] and KCons[H,T,M] + KList[M,HNil] and KNil
This commit is contained in:
parent
e41d4cc8c8
commit
2f41690269
|
|
@ -9,7 +9,7 @@ import Types._
|
|||
* type parameters HL. The underlying data is M applied to each type parameter.
|
||||
* Explicitly tracking M[_] allows performing natural transformations or ensuring
|
||||
* all data conforms to some common type. */
|
||||
sealed trait KList[+M[_], +HL <: HList]
|
||||
sealed trait KList[+M[_], HL <: HList]
|
||||
{
|
||||
type Raw = HL
|
||||
/** Transform to the underlying HList type.*/
|
||||
|
|
@ -20,6 +20,13 @@ sealed trait KList[+M[_], +HL <: HList]
|
|||
def toList: List[M[_]]
|
||||
/** Convert to an HList. */
|
||||
def combine[N[X] >: M[X]]: HL#Wrap[N]
|
||||
|
||||
def foldr[P[_ <: HList],N[X] >: M[X]](f: KFold[N,P]): P[HL]
|
||||
}
|
||||
trait KFold[M[_],P[_ <: HList]]
|
||||
{
|
||||
def kcons[H,T <: HList](h: M[H], acc: P[T]): P[H :+: T]
|
||||
def knil: P[HNil]
|
||||
}
|
||||
|
||||
final case class KCons[H, T <: HList, +M[_]](head: M[H], tail: KList[M,T]) extends KList[M, H :+: T]
|
||||
|
|
@ -33,6 +40,8 @@ final case class KCons[H, T <: HList, +M[_]](head: M[H], tail: KList[M,T]) exten
|
|||
def combine[N[X] >: M[X]]: (H :+: T)#Wrap[N] = HCons(head, tail.combine)
|
||||
|
||||
override def toString = head + " :^: " + tail.toString
|
||||
|
||||
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]
|
||||
|
|
@ -42,6 +51,7 @@ sealed class KNil extends KList[Nothing, HNil]
|
|||
def :^: [M[_], H](h: M[H]) = KCons(h, this)
|
||||
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
|
||||
|
|
@ -51,5 +61,12 @@ object KList
|
|||
// 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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue