task system cleanup

KList.map -> transform
can now drop trailing 'H' from multi-Task 'mapH'
compressed Action hierarchy by merging (Flat)Map{ped,All,Failure} into (Flat)Mapped
moved most information in Info into attributes: AttributeMap to allow future changes
This commit is contained in:
Mark Harrah 2010-08-21 22:55:42 -04:00
parent 48d5ec5da4
commit 5b21bae244
4 changed files with 49 additions and 8 deletions

View File

@ -0,0 +1,34 @@
/* sbt -- Simple Build Tool
* Copyright 2010 Mark Harrah
*/
package sbt
import Types._
// T must be invariant to work properly.
// Because it is sealed and the only instances go through make,
// a single AttributeKey instance cannot conform to AttributeKey[T] for different Ts
sealed trait AttributeKey[T]
object AttributeKey
{
def make[T]: AttributeKey[T] = new AttributeKey[T] {}
}
trait AttributeMap
{
def apply[T](k: AttributeKey[T]): T
def get[T](k: AttributeKey[T]): Option[T]
def contains[T](k: AttributeKey[T]): Boolean
def put[T](k: AttributeKey[T], value: T): AttributeMap
}
object AttributeMap
{
def empty: AttributeMap = new BasicAttributeMap(Map.empty)
}
private class BasicAttributeMap(backing: Map[AttributeKey[_], Any]) extends AttributeMap
{
def apply[T](k: AttributeKey[T]) = backing(k).asInstanceOf[T]
def get[T](k: AttributeKey[T]) = backing.get(k).asInstanceOf[Option[T]]
def contains[T](k: AttributeKey[T]) = backing.contains(k)
def put[T](k: AttributeKey[T], value: T): AttributeMap = new BasicAttributeMap( backing.updated(k, value) )
}

View File

@ -9,21 +9,23 @@ 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.*/
def down(implicit ev: M ~> Id): HL
/** Apply a natural transformation. */
def map[N[_]](f: M ~> N): KList[N, HL]
def transform[N[_]](f: M ~> N): KList[N, HL]
/** Convert to a List. */
def toList: List[M[_]]
/** Convert to an HList. */
def combine[N[X] >: M[X]]: HL#Wrap[N]
}
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 map[N[_]](f: M ~> N) = KCons( f(head), tail.map(f) )
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 toList = head :: tail.toList
@ -31,9 +33,10 @@ 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)
}
sealed class KNil extends KList[Nothing, HNil] {
sealed class KNil extends KList[Nothing, HNil]
{
def down(implicit f: Nothing ~> Id) = HNil
def map[N[_]](f: Nothing ~> N) = KNil
def transform[N[_]](f: Nothing ~> N) = KNil
def :^: [M[_], H](h: M[H]) = KCons(h, this)
def toList = Nil
def combine[N[X]] = HNil

View File

@ -8,4 +8,8 @@ object Types extends TypeFunctions
val :^: = KCons
val :+: = HCons
type :+:[H, T <: HList] = HCons[H,T]
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
}

View File

@ -9,7 +9,7 @@ object KTest {
val f = new (Option ~> List) { def apply[T](o: Option[T]): List[T] = o.toList }
val x = Some(3) :^: Some("asdf") :^: KNil
val y = x map f
val y = x transform f
val m1a = y match { case List(3) :^: List("asdf") :^: KNil => println("true") }
val m1b = (List(3) :^: KNil) match { case yy :^: KNil => println("true") }