2.10.0-M5, different arity generalization

1. KList[M[_]] now instead of KList[HL <: HList, M[_]]
  a. head, tail work properly in this variant
  b. disadvantage is that full type not easily transformed to new type constructor
2. AList abstracts on K[L[x]], a higher order type constructor.
 A. Instances written for:
  a. KList
  b. Seq[M[T]] for a fixed T
  c. TupleN
  d. single values
  e. operate on one type constructor when nested
 B. Main disadvantage is type inference.  It just doesn't happen for K[L[x]].
    This is mitigated by AList being used internally and rarely needing to construct a K.
This commit is contained in:
Mark Harrah 2012-07-31 11:52:10 -04:00
parent eecaeafbdf
commit 8d6dd10798
42 changed files with 622 additions and 709 deletions

View File

@ -5,7 +5,7 @@ import Prop._
object CacheTest extends Properties("Cache")
{
implicit val functions: Arbitrary[Int => Int] = Arbitrary { Gen.elements(identity[Int], i => -i, i=>i/2, i => i+1) }
implicit val functions: Arbitrary[Int => Int] = Arbitrary { Gen.oneOf( Seq(identity[Int], i => -i, i=>i/2, i => i+1) ) }
property("Cache") = Prop.forAll { (key: Int, keys: List[Int], map: Int => Int) =>
val cache = new Cache( (i: Int, _: Unit) => map(i) )

View File

@ -1,6 +1,7 @@
package xsbt.boot
import java.io.File
import java.util.Arrays.equals
import org.scalacheck._
object PreTest extends Properties("Pre")
@ -16,8 +17,8 @@ object PreTest extends Properties("Pre")
property("require true") = Prop.forAll { (s: String) => require(true, s); true }
property("error") = Prop.forAll( (s: String) => Prop.throws(error(s), classOf[BootException]) )
property("toBoolean") = Prop.forAll( (s: String) => trap(toBoolean(s)) == trap(java.lang.Boolean.parseBoolean(s)) )
property("toArray") = Prop.forAll( (list: List[Int]) => list.toArray deepEquals toArray(list) )
property("toArray") = Prop.forAll( (list: List[String]) => list.toArray deepEquals toArray(list) )
property("toArray") = Prop.forAll( (list: List[Int]) => equals(list.toArray, toArray(list)) )
property("toArray") = Prop.forAll( (list: List[String]) => equals(list.toArray, toArray(list)) )
property("concat") = Prop.forAll(genFiles, genFiles) { (a: Array[File], b: Array[File]) => (a ++ b) sameElements concat(a, b) }
property("array") = Prop.forAll(genFiles) { (a: Array[File]) => array(a.toList : _*) sameElements Array(a: _*) }

View File

@ -9,6 +9,7 @@ package sbt
import java.net.URI
import Parser._
import collection.mutable
import std.Transform.{DummyTaskMap, TaskAndValue}
sealed trait Aggregation
final object Aggregation
@ -27,9 +28,9 @@ final object Aggregation
def applyTasks[T](s: State, structure: BuildStructure, ps: Values[Parser[Task[T]]], show: Boolean)(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
Command.applyEffect(seqParser(ps)) { ts =>
runTasks(s, structure, ts, Dummies(KNil, HNil), show)
runTasks(s, structure, ts, DummyTaskMap(Nil), show)
}
def runTasksWithResult[HL <: HList, T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: Dummies[HL], show: Boolean)(implicit display: Show[ScopedKey[_]]): (State, Result[Seq[KeyValue[T]]]) =
def runTasksWithResult[T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: DummyTaskMap, show: Boolean)(implicit display: Show[ScopedKey[_]]): (State, Result[Seq[KeyValue[T]]]) =
{
import EvaluateTask._
import std.TaskExtra._
@ -41,7 +42,7 @@ final object Aggregation
val start = System.currentTimeMillis
val (newS, result) = withStreams(structure, s){ str =>
val transform = nodeView(s, str, roots, extra.tasks, extra.values)
val transform = nodeView(s, str, roots, extra)
runTask(toRun, s,str, structure.index.triggers, config)(transform)
}
val stop = System.currentTimeMillis
@ -54,7 +55,7 @@ final object Aggregation
(newS, result)
}
def runTasks[HL <: HList, T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: Dummies[HL], show: Boolean)(implicit display: Show[ScopedKey[_]]): State = {
def runTasks[HL <: HList, T](s: State, structure: BuildStructure, ts: Values[Task[T]], extra: DummyTaskMap, show: Boolean)(implicit display: Show[ScopedKey[_]]): State = {
runTasksWithResult(s, structure, ts, extra, show)._1
}
@ -92,14 +93,13 @@ final object Aggregation
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM)
}
final case class Dummies[HL <: HList](tasks: KList[Task,HL], values: HL)
def applyDynamicTasks[I](s: State, structure: BuildStructure, inputs: Values[InputDynamic[I]], show: Boolean)(implicit display: Show[ScopedKey[_]]): Parser[() => State] =
{
val parsers = inputs.map { case KeyValue(k,t) => KeyValue(k, t parser s) }
Command.applyEffect(seqParser(parsers)) { parseds =>
import EvaluateTask._
val inputMap = (Map.empty[AnyRef,Any] /: (inputs zip parseds)) { case (im, (id, v)) => im + ((id.value.defined, v.value)) }
val dummies = Dummies( InputTask.inputMap :^: KNil, inputMap :+: HNil)
val dummies = DummyTaskMap(new TaskAndValue(InputTask.inputMap, inputMap) :: Nil)
val roots = inputs.map { case KeyValue(k,t) => KeyValue(k,t.task) }
runTasks(s, structure, roots, dummies, show)
}

View File

@ -428,7 +428,7 @@ object Defaults extends BuildCommon
def packageSrcTask = packageSrcMappings
private type Mappings = Initialize[Task[Seq[(File, String)]]]
def concatMappings(as: Mappings, bs: Mappings) = (as zipWith bs)( (a,b) => (a :^: b :^: KNil) map { case a :+: b :+: HNil => a ++ b } )
def concatMappings(as: Mappings, bs: Mappings) = (as zipWith bs)( (a,b) => (a, b) map { case (a, b) => a ++ b } )
// drop base directories, since there are no valid mappings for these
def sourceMappings = (unmanagedSources, unmanagedSourceDirectories, baseDirectory) map { (srcs, sdirs, base) =>
@ -542,7 +542,7 @@ object Defaults extends BuildCommon
val srcs = in.config.sources
val hasScala = srcs.exists(_.name.endsWith(".scala"))
val hasJava = srcs.exists(_.name.endsWith(".java"))
val cp = in.config.classpath.toList - in.config.classesDirectory
val cp = in.config.classpath.toList.filterNot(_ == in.config.classesDirectory)
val label = nameForSrc(config.name)
val (options, runDoc) =
if(hasScala)
@ -741,7 +741,7 @@ object Classpaths
lazy val defaultArtifactTasks: Seq[TaskKey[File]] = makePom +: defaultPackages
def findClasspathConfig(map: Configuration => Configuration, thisConfig: Configuration, delegate: Task[Option[Configuration]], up: Task[UpdateReport]): Task[Configuration] =
(delegate :^: up :^: KNil) map { case delegated :+: report :+: HNil =>
(delegate, up) map { case (delegated, report) =>
val defined = report.allConfigurations.toSet
val search = map(thisConfig) +: (delegated.toList ++ Seq(Compile, Configurations.Default))
def notFound = error("Configuration to use for managed classpath must be explicitly defined when default configurations are not present.")
@ -950,7 +950,6 @@ object Classpaths
def cachedUpdate(cacheFile: File, label: String, module: IvySbt#Module, config: UpdateConfiguration, scalaInstance: Option[ScalaInstance], skip: Boolean, force: Boolean, depsUpdated: Boolean, log: Logger): UpdateReport =
{
implicit val updateCache = updateIC
implicit val updateReport = updateReportFormat
type In = IvyConfiguration :+: ModuleSettings :+: UpdateConfiguration :+: HNil
def work = (_: In) match { case conf :+: settings :+: config :+: HNil =>
log.info("Updating " + label + "...")
@ -1314,14 +1313,14 @@ trait BuildExtra extends BuildCommon
def fullRunInputTask(scoped: InputKey[Unit], config: Configuration, mainClass: String, baseArguments: String*): Setting[InputTask[Unit]] =
scoped <<= inputTask { result =>
( initScoped(scoped.scopedKey, runnerInit) zipWith (fullClasspath in config, streams, result).identityMap) { (rTask, t) =>
(t :^: rTask :^: KNil) map { case (cp, s, args) :+: r :+: HNil =>
(t, rTask) map { case ((cp, s, args), r) =>
toError(r.run(mainClass, data(cp), baseArguments ++ args, s.log))
}
}
}
def fullRunTask(scoped: TaskKey[Unit], config: Configuration, mainClass: String, arguments: String*): Setting[Task[Unit]] =
scoped <<= ( initScoped(scoped.scopedKey, runnerInit) zipWith (fullClasspath in config, streams).identityMap ) { case (rTask, t) =>
(t :^: rTask :^: KNil) map { case (cp, s) :+: r :+: HNil =>
(t, rTask) map { case ((cp, s), r) =>
toError(r.run(mainClass, data(cp), arguments, s.log))
}
}

View File

@ -11,6 +11,7 @@ package sbt
import Scope.{GlobalScope, ThisScope}
import Types.const
import scala.Console.RED
import std.Transform.{DummyTaskMap,TaskAndValue}
final case class EvaluateConfig(cancelable: Boolean, restrictions: Seq[Tags.Rule], checkCycles: Boolean = false)
final case class PluginData(dependencyClasspath: Seq[Attributed[File]], definitionClasspath: Seq[Attributed[File]], resolvers: Option[Seq[Resolver]], report: Option[UpdateReport])
@ -136,8 +137,8 @@ object EvaluateTask
for( t <- structure.data.get(resolvedScope, taskKey.key)) yield
(t, nodeView(state, streams, taskKey :: Nil))
}
def nodeView[HL <: HList](state: State, streams: Streams, roots: Seq[ScopedKey[_]], extraDummies: KList[Task, HL] = KNil, extraValues: HL = HNil): NodeView[Task] =
Transform(dummyRoots :^: dummyStreamsManager :^: KCons(dummyState, extraDummies), roots :+: streams :+: HCons(state, extraValues))
def nodeView[HL <: HList](state: State, streams: Streams, roots: Seq[ScopedKey[_]], dummies: DummyTaskMap = DummyTaskMap(Nil)): NodeView[Task] =
Transform((dummyRoots, roots) :: (dummyStreamsManager, streams) :: (dummyState, state) :: dummies )
def runTask[T](root: Task[T], state: State, streams: Streams, triggers: Triggers[Task], config: EvaluateConfig)(implicit taskToNode: NodeView[Task]): (State, Result[T]) =
{

View File

@ -3,6 +3,7 @@ package sbt
import Project._
import Scope.GlobalScope
import Def.{ScopedKey, Setting}
import std.Transform.DummyTaskMap
final case class Extracted(structure: BuildStructure, session: SessionSettings, currentRef: ProjectRef)(implicit val showKey: Show[ScopedKey[_]])
{
@ -30,7 +31,7 @@ final case class Extracted(structure: BuildStructure, session: SessionSettings,
val rkey = resolve(key.scopedKey)
val keys = Aggregation.aggregate(rkey, ScopeMask(), structure.extra)
val tasks = Act.keyValues(structure)(keys)
Aggregation.runTasks(state, structure, tasks, Aggregation.Dummies(KNil, HNil), show = false )(showKey)
Aggregation.runTasks(state, structure, tasks, DummyTaskMap(Nil), show = false )(showKey)
}
private[this] def resolve[T](key: ScopedKey[T]): ScopedKey[T] =
Project.mapScope(Scope.resolveScope(GlobalScope, currentRef.build, rootProject) )( key.scopedKey )

View File

@ -44,7 +44,7 @@ object Output
def lastLines(keys: Values[_], streams: Streams): Values[Seq[String]] =
{
val outputs = keys map { case KeyValue(key, value) => KeyValue(key, lastLines(key, streams)) }
val outputs = keys map { (kv: KeyValue[_]) => KeyValue(kv.key, lastLines(kv.key, streams)) }
outputs.filterNot(_.value.isEmpty)
}
def lastLines(key: ScopedKey[_], mgr: Streams): Seq[String] = mgr.use(key) { s => IO.readLines(s.readText( Project.fillTaskAxis(key) )) }

View File

@ -327,11 +327,6 @@ object Project extends ProjectExtra
EvaluateTask(extracted.structure, taskKey, state, extracted.currentRef, config)
}
/** Many methods were moved to Def in 0.13. This implicit makes those methods still available on Project for the transition. */
@inline
@deprecated("Use Def directly", "0.13.0")
implicit def projectToDef(p: Project.type): Def.type = Def
implicit def projectToRef(p: Project): ProjectReference = LocalProject(p.id)
final class RichTaskSessionVar[S](i: Initialize[Task[S]])

View File

@ -24,7 +24,7 @@ object SettingGraph
SettingGraph(display(scoped), definedIn,
Project.scopedKeyData(structure, scope, key),
key.description, basedir,
depends map { apply(structure, basedir, _, generation + 1) })
depends map { (x: ScopedKey[_]) => apply(structure, basedir, x, generation + 1) })
}
}

View File

@ -76,7 +76,9 @@ object InputTask
sealed trait Scoped { def scope: Scope; val key: AttributeKey[_] }
/** A common type for SettingKey and TaskKey so that both can be used as inputs to tasks.*/
sealed trait ScopedTaskable[T] extends Scoped
sealed trait ScopedTaskable[T] extends Scoped {
def toTask: Initialize[Task[T]]
}
/** Identifies a setting. It consists of three parts: the scope, the name, and the type of a value associated with this key.
* The scope is represented by a value of type Scope.
@ -85,6 +87,7 @@ sealed trait ScopedTaskable[T] extends Scoped
sealed trait SettingKey[T] extends ScopedTaskable[T] with KeyedInitialize[T] with Scoped.ScopingSetting[SettingKey[T]] with Scoped.DefinableSetting[T] with Scoped.ListSetting[T, Id]
{
val key: AttributeKey[T]
def toTask: Initialize[Task[T]] = this apply inlineTask
def scopedKey: ScopedKey[T] = ScopedKey(scope, key)
def in(scope: Scope): SettingKey[T] = Scoped.scopedSetting(Scope.replaceThis(this.scope)(scope), this.key)
@ -98,10 +101,11 @@ sealed trait SettingKey[T] extends ScopedTaskable[T] with KeyedInitialize[T] wit
sealed trait TaskKey[T] extends ScopedTaskable[T] with KeyedInitialize[Task[T]] with Scoped.ScopingSetting[TaskKey[T]] with Scoped.ListSetting[T, Task] with Scoped.DefinableTask[T]
{
val key: AttributeKey[Task[T]]
def toTask: Initialize[Task[T]] = this
def scopedKey: ScopedKey[Task[T]] = ScopedKey(scope, key)
def in(scope: Scope): TaskKey[T] = Scoped.scopedTask(Scope.replaceThis(this.scope)(scope), this.key)
protected[this] def make[S](other: Initialize[Task[S]])(f: (T, S) => T): Setting[Task[T]] = this <<= (this, other) { (a,b) => (a,b) map f }
protected[this] def make[S](other: Initialize[Task[S]])(f: (T, S) => T): Setting[Task[T]] = this <<= (this, other) { (a,b) => (a,b) map f.tupled }
}
/** Identifies an input task. An input task parses input and produces a task to run.
@ -189,7 +193,7 @@ object Scoped
def ? : Initialize[Task[Option[S]]] = Def.optional(scopedKey) { case None => mktask { None }; case Some(t) => t map some.fn }
def ??[T >: S](or: => T): Initialize[Task[T]] = Def.optional(scopedKey)( _ getOrElse mktask(or) )
def or[T >: S](i: Initialize[Task[T]]): Initialize[Task[T]] = (this.? zipWith i)( (x,y) => (x :^: y :^: KNil) map hf2( _ getOrElse _ ))
def or[T >: S](i: Initialize[Task[T]]): Initialize[Task[T]] = (this.? zipWith i)( (x,y) => (x, y) map { case (a,b) => a getOrElse b})
}
final class RichInitializeTask[S](i: Initialize[Task[S]]) extends RichInitTaskBase[S, Task]
{
@ -248,87 +252,26 @@ object Scoped
final class RichFileSetting(s: SettingKey[File]) extends RichFileBase
{
@deprecated("Use a standard setting definition.", "0.13.0")
def /(c: String): Initialize[File] = s { _ / c }
protected[this] def map0(f: PathFinder => PathFinder) = s(file => finder(f)(file :: Nil))
}
final class RichFilesSetting(s: SettingKey[Seq[File]]) extends RichFileBase
{
@deprecated("Use a standard setting definition.", "0.13.0")
def /(s: String): Initialize[Seq[File]] = map0 { _ / s }
protected[this] def map0(f: PathFinder => PathFinder) = s(finder(f))
}
sealed abstract class RichFileBase
{
@deprecated("Use a standard setting definition.", "0.13.0")
def *(filter: FileFilter): Initialize[Seq[File]] = map0 { _ * filter }
@deprecated("Use a standard setting definition.", "0.13.0")
def **(filter: FileFilter): Initialize[Seq[File]] = map0 { _ ** filter }
protected[this] def map0(f: PathFinder => PathFinder): Initialize[Seq[File]]
protected[this] def finder(f: PathFinder => PathFinder): Seq[File] => Seq[File] =
in => f(in).get
}
/*
* Reduced and combine provide support for mixed Setting/Task flatMap/map.
* The general idea is to take a KList of ScopedTaskables, which are either SettingKeys or TaskKeys,
* and uniformly provide multi-flatMap/map for constructing a new Task.
* For example: {{{ (SettingKeyA, TaskKeyB) flatMap { (a,b) => ... } }}}
*/
trait Reduced[HLs <: HList, HLt <: HList, HLv <: HList]
{ o =>
def settings: KList[Initialize, HLs] // SS[A] :^: SS[Task[B]] :^: ...
def tasks(hls: HLs): KList[Task, HLt] // takes setting values from previous line to Task[B] :^: ...
def expand(hls: HLs, hlt: Results[HLt]): Results[HLv] // takes Result[B] :+: ... to Value[A] :+: Result[B] :+: ...
def prependTask[H](key: Initialize[Task[H]]) =
new Reduced[Task[H] :+: HLs, H :+: HLt, H :+: HLv]
{
val settings = KCons(key, o.settings)
def tasks(hls: Task[H] :+: HLs) = KCons(hls.head, o.tasks(hls.tail))
def expand(hls: Task[H] :+: HLs, hlt: Results[H :+: HLt]) = KCons(hlt.head, o.expand(hls.tail, hlt.tail) )
}
def prependSetting[H](key: Initialize[H]) =
new Reduced[H :+: HLs, HLt, H :+: HLv]
{
val settings = KCons(key, o.settings)
def tasks(hls: H :+: HLs) = o.tasks(hls.tail)
def expand(hls: H :+: HLs, hlt: Results[HLt]) = KCons(Value(hls.head), o.expand(hls.tail, hlt))
}
def prependTaskable[H](key: ScopedTaskable[H]): Reduced[_,_,H :+: HLv] =
key match
{
case ss: SettingKey[H] => prependSetting(ss)
case st: TaskKey[H] => prependTask(scopedSetting(st.scope, st.key))
}
def combine[D[_],S](c: Combine[D], f: Results[HLv] => D[S]): Initialize[Task[S]] =
Def.app(settings)(hls => c(tasks(hls))(hlt => f(expand(hls, hlt))) )
}
type RedHL[HL <: HList] = Reduced[_,_,HL]
def reduced[HL <: HList](settings: KList[ScopedTaskable, HL]): Reduced[_,_,HL] =
settings.foldr { new KFold[ScopedTaskable, RedHL] {
def knil = emptyReduced
def kcons[H,T<:HList](h: ScopedTaskable[H], acc: Reduced[_,_,T]): Reduced[_,_,H :+: T] =
acc prependTaskable h
}}
def emptyReduced: Reduced[HNil,HNil,HNil] = new Reduced[HNil,HNil,HNil] {
def settings = KNil
def tasks(h: HNil) = KNil
def expand(a: HNil, k: Results[HNil]) = KNil
}
trait Combine[D[_]] {
def apply[HL <: HList,S](tasks: KList[Task, HL])(f: Results[HL] => D[S]): Task[S]
}
object Combine
{
val mapR: Combine[Id] = new Combine[Id] {
def apply[HL <: HList,S](tasks: KList[Task, HL])(f: Results[HL] => S): Task[S] =
tasks mapR f
}
val flatMapR: Combine[Task] = new Combine[Task] {
def apply[HL <: HList,S](tasks: KList[Task, HL])(f: Results[HL] => Task[S]): Task[S] =
tasks flatMapR f
}
}
// this is the least painful arrangement I came up with
implicit def t2ToTable2[A,B](t2: (ScopedTaskable[A], ScopedTaskable[B]) ): RichTaskable2[A,B] = new RichTaskable2(t2)
@ -341,145 +284,133 @@ object Scoped
implicit def t9ToTable9[A,B,C,D,E,F,G,H,I](t9: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I]) ): RichTaskable9[A,B,C,D,E,F,G,H,I] = new RichTaskable9(t9)
implicit def t10ToTable10[A,B,C,D,E,F,G,H,I,J](t10: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J]) ): RichTaskable10[A,B,C,D,E,F,G,H,I,J] = new RichTaskable10(t10)
implicit def t11ToTable11[A,B,C,D,E,F,G,H,I,J,K](t11: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K]) ): RichTaskable11[A,B,C,D,E,F,G,H,I,J,K] = new RichTaskable11(t11)
implicit def t12ToTable12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L]) ): RichTaskable12[A,B,C,D,E,F,G,H,I,J,K,L] = new RichTaskable12(t12)
/* implicit def t12ToTable12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L]) ): RichTaskable12[A,B,C,D,E,F,G,H,I,J,K,L] = new RichTaskable12(t12)
implicit def t13ToTable13[A,B,C,D,E,F,G,H,I,J,K,L,N](t13: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N]) ): RichTaskable13[A,B,C,D,E,F,G,H,I,J,K,L,N] = new RichTaskable13(t13)
implicit def t14ToTable14[A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N], ScopedTaskable[O]) ): RichTaskable14[A,B,C,D,E,F,G,H,I,J,K,L,N,O] = new RichTaskable14(t14)
implicit def t15ToTable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N], ScopedTaskable[O], ScopedTaskable[P]) ): RichTaskable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P] = new RichTaskable15(t15)
implicit def t15ToTable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N], ScopedTaskable[O], ScopedTaskable[P]) ): RichTaskable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P] = new RichTaskable15(t15)*/
sealed abstract class RichTaskables[In <: HList](keys: KList[ScopedTaskable, In])
sealed abstract class RichTaskables[K[L[x]]](final val keys: K[ScopedTaskable])(implicit a: AList[K])
{
type App[T] = Initialize[Task[T]]
type Fun[M[_],Ret]
protected def convertH[Ret](f: Fun[Id,Ret]): In => Ret
protected def convertK[M[_],Ret](f: Fun[M,Ret]): KList[M,In] => Ret
private[this] val red = reduced(keys)
protected def convert[M[_],Ret](f: Fun[M,Ret]): K[M] => Ret
private[this] val inputs: K[App] = a.transform(keys, new (ScopedTaskable ~> App) { def apply[T](in: ScopedTaskable[T]): App[T] = in.toTask })
private[this] def onTasks[T](f: K[Task] => Task[T]): App[T] = Def.app[({ type l[L[x]] = K[ (L Task)#l] })#l,Task[T]](inputs)(f)(AList.asplit[K,Task](a))
def flatMap[T](f: Fun[Id,Task[T]]): App[T] = red.combine(Combine.flatMapR, convertH(f) compose allM)
def flatMapR[T](f: Fun[Result,Task[T]]): App[T] = red.combine(Combine.flatMapR, convertK(f))
def map[T](f: Fun[Id, T]): App[T] = red.combine[Id,T](Combine.mapR, convertH(f) compose allM)
def mapR[T](f: Fun[Result,T]): App[T] = red.combine[Id,T](Combine.mapR, convertK(f))
def flatFailure[T](f: Seq[Incomplete] => Task[T]): App[T] = red.combine(Combine.flatMapR, f compose anyFailM)
def mapFailure[T](f: Seq[Incomplete] => T): App[T] = red.combine[Id,T](Combine.mapR, f compose anyFailM)
def flatMap[T](f: Fun[Id,Task[T]]): App[T] = onTasks(_.flatMap(convert(f)))
def flatMapR[T](f: Fun[Result,Task[T]]): App[T] = onTasks(_.flatMapR(convert(f)))
def map[T](f: Fun[Id, T]): App[T] = onTasks(_.mapR( convert(f) compose allM))
def mapR[T](f: Fun[Result,T]): App[T] = onTasks(_.mapR(convert(f)))
def flatFailure[T](f: Seq[Incomplete] => Task[T]): App[T] = onTasks(_ flatFailure f)
def mapFailure[T](f: Seq[Incomplete] => T): App[T] = onTasks(_ mapFailure f)
}
final class RichTaskable2[A,B](t2: (ScopedTaskable[A], ScopedTaskable[B])) extends RichTaskables(k2(t2))
type :@:[H, T <: KList[ScopedTaskable]] = KCons[H, T, ScopedTaskable]
type ST[X] = ScopedTaskable[X]
final class RichTaskable2[A,B](t2: (ST[A], ST[B])) extends RichTaskables[ AList.T2K[A,B]#l ](t2)(AList.tuple2[A,B])
{
type Fun[M[_],Ret] = (M[A],M[B]) => Ret
def identityMap = map(mkTuple2)
protected def convertH[R](z: (A,B) => R) = hf2(z)
protected def convertK[M[_],R](f: (M[A],M[B]) => R) = { case a :^: b :^: KNil => f(a,b) }
protected def convert[M[_],R](f: (M[A],M[B]) => R) = f.tupled
}
final class RichTaskable3[A,B,C](t3: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C])) extends RichTaskables(k3(t3))
final class RichTaskable3[A,B,C](t3: (ST[A], ST[B], ST[C])) extends RichTaskables[ AList.T3K[A,B,C]#l](t3)(AList.tuple3[A,B,C])
{
type Fun[M[_],Ret] = (M[A],M[B],M[C]) => Ret
def identityMap = map(mkTuple3)
protected def convertH[R](z: Fun[Id,R]) = hf3(z)
protected def convertK[M[_],R](f: Fun[M,R]) = { case a :^: b :^: c :^: KNil => f(a,b,c) }
protected def convert[M[_],R](f: Fun[M,R]) = f.tupled
}
final class RichTaskable4[A,B,C,D](t4: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D])) extends RichTaskables(k4(t4))
final class RichTaskable4[A,B,C,D](t4: (ST[A], ST[B], ST[C], ST[D])) extends RichTaskables[ AList.T4K[A,B,C,D]#l](t4)(AList.tuple4[A,B,C,D])
{
type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D]) => Ret
def identityMap = map(mkTuple4)
protected def convertH[R](z: Fun[Id,R]) = hf4(z)
protected def convertK[M[_],R](f: Fun[M,R]) = { case a :^: b :^: c :^: d :^: KNil => f(a,b,c,d) }
protected def convert[M[_],R](f: Fun[M,R]) = f.tupled
}
final class RichTaskable5[A,B,C,D,E](t5: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E])) extends RichTaskables(k5(t5))
final class RichTaskable5[A,B,C,D,E](t5: (ST[A], ST[B], ST[C], ST[D], ST[E])) extends RichTaskables[AList.T5K[A,B,C,D,E]#l](t5)(AList.tuple5[A,B,C,D,E])
{
type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D],M[E]) => Ret
def identityMap = map(mkTuple5)
protected def convertH[R](z: Fun[Id,R]) = hf5(z)
protected def convertK[M[_],R](f: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: KNil => f(a,b,c,d,e) }
protected def convert[M[_],R](f: Fun[M,R]) = f.tupled
}
final class RichTaskable6[A,B,C,D,E,F](t6: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F])) extends RichTaskables(k6(t6))
final class RichTaskable6[A,B,C,D,E,F](t6: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F])) extends RichTaskables[AList.T6K[A,B,C,D,E,F]#l](t6)(AList.tuple6[A,B,C,D,E,F])
{
type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D],M[E],M[F]) => Ret
def identityMap = map(mkTuple6)
protected def convertH[R](z: Fun[Id,R]) = hf6(z)
protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: KNil => z(a,b,c,d,e,f) }
protected def convert[M[_],R](z: Fun[M,R]) = z.tupled
}
final class RichTaskable7[A,B,C,D,E,F,G](t7: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G])) extends RichTaskables(k7(t7))
final class RichTaskable7[A,B,C,D,E,F,G](t7: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G])) extends RichTaskables[AList.T7K[A,B,C,D,E,F,G]#l](t7)(AList.tuple7[A,B,C,D,E,F,G])
{
type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D],M[E],M[F],M[G]) => Ret
def identityMap = map(mkTuple7)
protected def convertH[R](z: Fun[Id,R]) = hf7(z)
protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: KNil => z(a,b,c,d,e,f,g) }
protected def convert[M[_],R](z: Fun[M,R]) = z.tupled
}
final class RichTaskable8[A,B,C,D,E,F,G,H](t8: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H])) extends RichTaskables(k8(t8))
final class RichTaskable8[A,B,C,D,E,F,G,H](t8: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H])) extends RichTaskables[AList.T8K[A,B,C,D,E,F,G,H]#l](t8)(AList.tuple8[A,B,C,D,E,F,G,H])
{
type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D],M[E],M[F],M[G],M[H]) => Ret
def identityMap = map(mkTuple8)
protected def convertH[R](z: Fun[Id,R]) = hf8(z)
protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: KNil => z(a,b,c,d,e,f,g,h) }
protected def convert[M[_],R](z: Fun[M,R]) = z.tupled
}
final class RichTaskable9[A,B,C,D,E,F,G,H,I](t9: (ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I])) extends RichTaskables(k9(t9))
final class RichTaskable9[A,B,C,D,E,F,G,H,I](t9: (ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I])) extends RichTaskables[AList.T9K[A,B,C,D,E,F,G,H,I]#l](t9)(AList.tuple9[A,B,C,D,E,F,G,H,I])
{
type Fun[M[_],Ret] = (M[A],M[B],M[C],M[D],M[E],M[F],M[G],M[H],M[I]) => Ret
def identityMap = map(mkTuple9)
protected def convertH[R](z: Fun[Id,R]) = hf9(z)
protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: KNil => z(a,b,c,d,e,f,g,h,i) }
protected def convert[M[_],R](z: Fun[M,R]) = z.tupled
}
final class RichTaskable10[A,B,C,D,E,F,G,H,I,J](t10: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J]))) extends RichTaskables(k10(t10))
final class RichTaskable10[A,B,C,D,E,F,G,H,I,J](t10: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J]))) extends RichTaskables[AList.T10K[A,B,C,D,E,F,G,H,I,J]#l](t10)(AList.tuple10[A,B,C,D,E,F,G,H,I,J])
{
type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J]) => Ret
def identityMap = map(mkTuple10)
protected def convertH[R](z: Fun[Id,R]) = hf10(z)
protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: KNil => z(a,b,c,d,e,f,g,h,i,j) }
protected def convert[M[_],R](z: Fun[M,R]) = z.tupled
}
final class RichTaskable11[A,B,C,D,E,F,G,H,I,J,K](t11: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K]))) extends RichTaskables(k11(t11))
final class RichTaskable11[A,B,C,D,E,F,G,H,I,J,K](t11: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K]))) extends RichTaskables[AList.T11K[A,B,C,D,E,F,G,H,I,J,K]#l](t11)(AList.tuple11[A,B,C,D,E,F,G,H,I,J,K])
{
type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K]) => Ret
def identityMap = map(mkTuple11)
protected def convertH[R](z: Fun[Id,R]) = hf11(z)
protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: k :^: KNil => z(a,b,c,d,e,f,g,h,i,j,k) }
protected def convert[M[_],R](z: Fun[M,R]) = z.tupled
}
final class RichTaskable12[A,B,C,D,E,F,G,H,I,J,K,L](t12: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L]))) extends RichTaskables(k12(t12))
/* final class RichTaskable12[A,B,C,D,E,F,G,H,I,J,K,L](t12: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K], ST[L]))) extends RichTaskables(k12(t12))
{
type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L]) => Ret
def identityMap = map(mkTuple12)
protected def convertH[R](z: Fun[Id,R]) = hf12(z)
protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: k :^: l :^: KNil => z(a,b,c,d,e,f,g,h,i,j,k,l) }
protected def convert[M[_],R](z: Fun[M,R]) = z.tupled
}
final class RichTaskable13[A,B,C,D,E,F,G,H,I,J,K,L,N](t13: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N]))) extends RichTaskables(k13(t13))
final class RichTaskable13[A,B,C,D,E,F,G,H,I,J,K,L,N](t13: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K], ST[L], ST[N]))) extends RichTaskables(k13(t13))
{
type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N]) => Ret
def identityMap = map(mkTuple13)
protected def convertH[R](z: Fun[Id,R]) = hf13(z)
protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: k :^: l :^: n :^: KNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n) }
protected def convert[M[_],R](z: Fun[M,R]) = z.tupled
}
final class RichTaskable14[A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N], ScopedTaskable[O]))) extends RichTaskables(k14(t14))
final class RichTaskable14[A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K], ST[L], ST[N], ST[O]))) extends RichTaskables(k14(t14))
{
type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N], M[O]) => Ret
def identityMap = map(mkTuple14)
protected def convertH[R](z: Fun[Id,R]) = hf14(z)
protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: k :^: l :^: n :^: o :^: KNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n,o) }
protected def convert[M[_],R](z: Fun[M,R]) = z.tupled
}
final class RichTaskable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: ((ScopedTaskable[A], ScopedTaskable[B], ScopedTaskable[C], ScopedTaskable[D], ScopedTaskable[E], ScopedTaskable[F], ScopedTaskable[G], ScopedTaskable[H], ScopedTaskable[I], ScopedTaskable[J], ScopedTaskable[K], ScopedTaskable[L], ScopedTaskable[N], ScopedTaskable[O], ScopedTaskable[P]))) extends RichTaskables(k15(t15))
final class RichTaskable15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: ((ST[A], ST[B], ST[C], ST[D], ST[E], ST[F], ST[G], ST[H], ST[I], ST[J], ST[K], ST[L], ST[N], ST[O], ST[P]))) extends RichTaskables(k15(t15))
{
type Fun[M[_],Ret] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N], M[O], M[P]) => Ret
def identityMap = map(mkTuple15)
protected def convertH[R](z: Fun[Id,R]) = hf15(z)
protected def convertK[M[_],R](z: Fun[M,R]) = { case a :^: b :^: c :^: d :^: e :^: f :^: g :^: h :^: i :^: j :^: k :^: l :^: n :^: o :^: p :^: KNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n,o,p) }
}
protected def convert[M[_],R](z: Fun[M,R]) = z.tupled
}*/
// this doesn't actually work for mixed KLists because the compiler crashes trying to infer the bound when constructing the KList
implicit def richTaskableKeys[HL <: HList](in: KList[ScopedTaskable, HL]): RichTaskableKeys[HL] = new RichTaskableKeys(in)
final class RichTaskableKeys[In <: HList](keys: KList[ScopedTaskable, In])
/* implicit def richTaskableKeys[KL <: KList[ScopedTaskable]](in: KList): RichTaskableKeys[KL] = new RichTaskableKeys[KL](in)
final class RichTaskableKeys[KL <: KList[ScopedTaskable]](keys: KL)
{
type App[T] = Initialize[Task[T]]
private[this] val red = reduced(keys)
private[this] def inputs: keys.Transform[App] = keys.transform( new (ScopedTaskable ~> App) { def apply[T](in: ScopedTaskable[T]): App[T] = in.toTask })
def identity: App[In] = map(idFun)
def flatMap[T](f: In => Task[T]): App[T] = flatMapR(f compose allM)
def flatMapR[T](f: Results[In] => Task[T]): App[T] = red.combine(Combine.flatMapR, f)
def flatMap[T](f: keys.Transform[Id] => Task[T]): App[T] = flatMapR(f compose allM)
def flatMapR[T](f: keys.Transform[Result] => Task[T]): App[T] = red.combine(Combine.flatMapR, f)
def map[T](f: In => T): App[T] = mapR(f compose allM)
def mapR[T](f: Results[In] => T): App[T] = red.combine[Id,T](Combine.mapR, f)
def flatFailure[T](f: Seq[Incomplete] => Task[T]): App[T] = flatMapR(f compose anyFailM)
def mapFailure[T](f: Seq[Incomplete] => T): App[T] = mapR(f compose anyFailM)
}
}*/
implicit def t2ToApp2[A,B](t2: (Initialize[A], Initialize[B]) ): Apply2[A,B] = new Apply2(t2)
implicit def t3ToApp3[A,B,C](t3: (Initialize[A], Initialize[B], Initialize[C]) ): Apply3[A,B,C] = new Apply3(t3)
@ -491,11 +422,11 @@ object Scoped
implicit def t9ToApp9[A,B,C,D,E,F,G,H,I](t9: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I]) ): Apply9[A,B,C,D,E,F,G,H,I] = new Apply9(t9)
implicit def t10ToApp10[A,B,C,D,E,F,G,H,I,J](t10: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J]) ): Apply10[A,B,C,D,E,F,G,H,I,J] = new Apply10(t10)
implicit def t11ToApp11[A,B,C,D,E,F,G,H,I,J,K](t11: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K]) ): Apply11[A,B,C,D,E,F,G,H,I,J,K] = new Apply11(t11)
implicit def t12ToApp12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L]) ): Apply12[A,B,C,D,E,F,G,H,I,J,K,L] = new Apply12(t12)
/* implicit def t12ToApp12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L]) ): Apply12[A,B,C,D,E,F,G,H,I,J,K,L] = new Apply12(t12)
implicit def t13ToApp13[A,B,C,D,E,F,G,H,I,J,K,L,N](t13: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N]) ): Apply13[A,B,C,D,E,F,G,H,I,J,K,L,N] = new Apply13(t13)
implicit def t14ToApp14[A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N], Initialize[O]) ): Apply14[A,B,C,D,E,F,G,H,I,J,K,L,N,O] = new Apply14(t14)
implicit def t15ToApp15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L], Initialize[N], Initialize[O], Initialize[P]) ): Apply15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P] = new Apply15(t15)
*/
def mkTuple2[A,B] = (a:A,b:B) => (a,b)
def mkTuple3[A,B,C] = (a:A,b:B,c:C) => (a,b,c)
def mkTuple4[A,B,C,D] = (a:A,b:B,c:C,d:D) => (a,b,c,d)
@ -512,46 +443,46 @@ object Scoped
def mkTuple15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P] = (a:A,b:B,c:C,d:D,e:E,f:F,g:G,h:H,i:I,j:J,k:K,l:L,n:N,o:O,p:P) => (a,b,c,d,e,f,g,h,i,j,k,l,n,o,p)
final class Apply2[A,B](t2: (Initialize[A], Initialize[B])) {
def apply[T](z: (A,B) => T) = Def.app( k2(t2) )( hf2(z) )
def apply[T](z: (A,B) => T) = Def.app[AList.T2K[A,B]#l, T]( t2 )( z.tupled )(AList.tuple2[A,B])
def identity = apply(mkTuple2)
}
final class Apply3[A,B,C](t3: (Initialize[A], Initialize[B], Initialize[C])) {
def apply[T](z: (A,B,C) => T) = Def.app( k3(t3) )( hf3(z) )
def apply[T](z: (A,B,C) => T) = Def.app[AList.T3K[A,B,C]#l, T]( t3 )( z.tupled )(AList.tuple3[A,B,C])
def identity = apply(mkTuple3)
}
final class Apply4[A,B,C,D](t4: (Initialize[A], Initialize[B], Initialize[C], Initialize[D])) {
def apply[T](z: (A,B,C,D) => T) = Def.app( k4(t4) )( hf4(z) )
def apply[T](z: (A,B,C,D) => T) = Def.app[AList.T4K[A,B,C,D]#l, T]( t4 )( z.tupled )(AList.tuple4[A,B,C,D])
def identity = apply(mkTuple4)
}
final class Apply5[A,B,C,D,E](t5: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E])) {
def apply[T](z: (A,B,C,D,E) => T) = Def.app( k5(t5) )( hf5(z) )
def apply[T](z: (A,B,C,D,E) => T) = Def.app[AList.T5K[A,B,C,D,E]#l, T]( t5 )( z.tupled )( AList.tuple5[A,B,C,D,E] )
def identity = apply(mkTuple5)
}
final class Apply6[A,B,C,D,E,F](t6: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F])) {
def apply[T](z: (A,B,C,D,E,F) => T) = Def.app( k6(t6) )( hf6(z) )
def apply[T](z: (A,B,C,D,E,F) => T) = Def.app[AList.T6K[A,B,C,D,E,F]#l, T]( t6 )( z.tupled )( AList.tuple6[A,B,C,D,E,F] )
def identity = apply(mkTuple6)
}
final class Apply7[A,B,C,D,E,F,G](t7: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G])) {
def apply[T](z: (A,B,C,D,E,F,G) => T) = Def.app( k7(t7) )( hf7(z) )
def apply[T](z: (A,B,C,D,E,F,G) => T) = Def.app[AList.T7K[A,B,C,D,E,F,G]#l, T]( t7 )( z.tupled )( AList.tuple7[A,B,C,D,E,F,G] )
def identity = apply(mkTuple7)
}
final class Apply8[A,B,C,D,E,F,G,H](t8: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H])) {
def apply[T](z: (A,B,C,D,E,F,G,H) => T) = Def.app( k8(t8) )( hf8(z) )
def apply[T](z: (A,B,C,D,E,F,G,H) => T) = Def.app[AList.T8K[A,B,C,D,E,F,G,H]#l, T]( t8 )( z.tupled )( AList.tuple8[A,B,C,D,E,F,G,H] )
def identity = apply(mkTuple8)
}
final class Apply9[A,B,C,D,E,F,G,H,I](t9: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I])) {
def apply[T](z: (A,B,C,D,E,F,G,H,I) => T) = Def.app( k9(t9) )( hf9(z) )
def apply[T](z: (A,B,C,D,E,F,G,H,I) => T) = Def.app[AList.T9K[A,B,C,D,E,F,G,H,I]#l, T]( t9 )( z.tupled )( AList.tuple9[A,B,C,D,E,F,G,H,I] )
def identity = apply(mkTuple9)
}
final class Apply10[A,B,C,D,E,F,G,H,I,J](t10: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J])) {
def apply[T](z: (A,B,C,D,E,F,G,H,I,J) => T) = Def.app( k10(t10) )( hf10(z) )
def apply[T](z: (A,B,C,D,E,F,G,H,I,J) => T) = Def.app[AList.T10K[A,B,C,D,E,F,G,H,I,J]#l, T]( t10 )( z.tupled )( AList.tuple10[A,B,C,D,E,F,G,H,I,J] )
def identity = apply(mkTuple10)
}
final class Apply11[A,B,C,D,E,F,G,H,I,J,K](t11: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K])) {
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K) => T) = Def.app( k11(t11) )( hf11(z) )
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K) => T) = Def.app[AList.T11K[A,B,C,D,E,F,G,H,I,J,K]#l, T]( t11 )( z.tupled )( AList.tuple11[A,B,C,D,E,F,G,H,I,J,K] )
def identity = apply(mkTuple11)
}
final class Apply12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L])) {
/* final class Apply12[A,B,C,D,E,F,G,H,I,J,K,L](t12: (Initialize[A], Initialize[B], Initialize[C], Initialize[D], Initialize[E], Initialize[F], Initialize[G], Initialize[H], Initialize[I], Initialize[J], Initialize[K], Initialize[L])) {
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L) => T) = Def.app( k12(t12) )( hf12(z) )
def identity = apply(mkTuple12)
}
@ -567,38 +498,7 @@ object Scoped
def apply[T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N,O,P) => T) = Def.app( k15(t15) )( hf15(z) )
def identity = apply(mkTuple15)
}
def hf2[A, B, T](z: (A, B) => T): A :+: B :+: HNil => T = { case a :+: b :+: HNil => z(a,b) }
def hf3[A, B, C, T](z: (A,B,C) => T): A :+: B :+: C :+: HNil => T = { case a :+: b :+: c :+: HNil => z(a,b,c) }
def hf4[A, B, C, D, T](z: (A,B,C,D) => T): A :+: B :+: C :+: D :+: HNil => T = { case a :+: b :+: c :+: d :+: HNil => z(a,b,c,d) }
def hf5[A, B, C, D, E, T](z: (A,B,C,D,E) => T): A :+: B :+: C :+: D :+: E :+: HNil => T = { case a :+: b :+: c :+: d :+: e :+: HNil => z(a,b,c,d,e) }
def hf6[A, B, C, D, E, F, T](z: (A,B,C,D,E,F) => T): A :+: B :+: C :+: D :+: E :+: F :+: HNil => T = { case a :+: b :+: c :+: d :+: e :+: f :+: HNil => z(a,b,c,d,e,f) }
def hf7[A, B, C, D, E, F, G, T](z: (A,B,C,D,E,F,G) => T): A :+: B :+: C :+: D :+: E :+: F :+: G :+: HNil => T = { case a :+: b :+: c :+: d :+: e :+: f :+: g :+: HNil => z(a,b,c,d,e,f,g) }
def hf8[A, B, C, D, E, F, G, H, T](z: (A,B,C,D,E,F,G,H) => T): A :+: B :+: C :+: D :+: E :+: F :+: G :+: H :+: HNil => T = { case a :+: b :+: c :+: d :+: e :+: f :+: g :+: h :+: HNil => z(a,b,c,d,e,f,g,h) }
def hf9[A, B, C, D, E, F, G, H, I, T](z: (A,B,C,D,E,F,G,H,I) => T): A :+: B :+: C :+: D :+: E :+: F :+: G :+: H :+: I :+: HNil => T = { case a :+: b :+: c :+: d :+: e :+: f :+: g :+: h :+: i :+: HNil => z(a,b,c,d,e,f,g,h,i) }
def hf10[A,B,C,D,E,F,G,H,I,J,T](z: (A,B,C,D,E,F,G,H,I,J) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j :+: HNil => z(a,b,c,d,e,f,g,h,i,j) }
def hf11[A,B,C,D,E,F,G,H,I,J,K,T](z: (A,B,C,D,E,F,G,H,I,J,K) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J:+:K :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j:+:k :+: HNil => z(a,b,c,d,e,f,g,h,i,j,k) }
def hf12[A,B,C,D,E,F,G,H,I,J,K,L,T](z: (A,B,C,D,E,F,G,H,I,J,K,L) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J:+:K:+:L :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j:+:k:+:l :+: HNil => z(a,b,c,d,e,f,g,h,i,j,k,l) }
def hf13[A,B,C,D,E,F,G,H,I,J,K,L,N,T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J:+:K:+:L:+:N :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j:+:k:+:l:+:n :+: HNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n) }
def hf14[A,B,C,D,E,F,G,H,I,J,K,L,N,O,T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N,O) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J:+:K:+:L:+:N:+:O :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j:+:k:+:l:+:n:+:o :+: HNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n,o) }
def hf15[A,B,C,D,E,F,G,H,I,J,K,L,N,O,P,T](z: (A,B,C,D,E,F,G,H,I,J,K,L,N,O,P) => T): A:+:B:+:C:+:D:+:E:+:F:+:G:+:H:+:I:+:J:+:K:+:L:+:N:+:O:+:P :+: HNil => T = { case a:+:b:+:c:+:d:+:e:+:f:+:g:+:h:+:i:+:j:+:k:+:l:+:n:+:o:+:p :+: HNil => z(a,b,c,d,e,f,g,h,i,j,k,l,n,o,p) }
def k2[M[_], A, B](t2: (M[A], M[B]) ) = t2._1 :^: t2._2 :^: KNil
def k3[M[_], A, B, C](t3: (M[A], M[B], M[C]) ) = t3._1 :^: t3._2 :^: t3._3 :^: KNil
def k4[M[_], A, B, C, D](t4: (M[A], M[B], M[C], M[D])) = t4._1 :^: t4._2 :^: t4._3 :^: t4._4 :^: KNil
def k5[M[_], A, B, C, D, E](t5: (M[A], M[B], M[C], M[D], M[E])) = t5._1 :^: t5._2 :^: t5._3 :^: t5._4 :^: t5._5 :^: KNil
def k6[M[_], A, B, C, D, E, F](t6: (M[A], M[B], M[C], M[D], M[E], M[F])) = t6._1 :^: t6._2 :^: t6._3 :^: t6._4 :^: t6._5 :^: t6._6 :^: KNil
def k7[M[_], A, B, C, D, E, F, G](t7: (M[A], M[B], M[C], M[D], M[E], M[F], M[G])) = t7._1 :^: t7._2 :^: t7._3 :^: t7._4 :^: t7._5 :^: t7._6 :^: t7._7 :^: KNil
def k8[M[_], A, B, C, D, E, F, G, H](t8: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H])) = t8._1 :^: t8._2 :^: t8._3 :^: t8._4 :^: t8._5 :^: t8._6 :^: t8._7 :^: t8._8 :^: KNil
def k9[M[_], A, B, C, D, E, F, G, H, I](t9: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I])) = t9._1 :^: t9._2 :^: t9._3 :^: t9._4 :^: t9._5 :^: t9._6 :^: t9._7 :^: t9._8 :^: t9._9 :^: KNil
def k10[M[_], A,B,C,D,E,F,G,H,I,J](t10: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J])) =t10._1 :^:t10._2 :^:t10._3 :^:t10._4 :^:t10._5 :^:t10._6 :^:t10._7 :^:t10._8 :^:t10._9 :^:t10._10 :^: KNil
def k11[M[_], A,B,C,D,E,F,G,H,I,J,K](t11: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K])) =t11._1 :^:t11._2 :^:t11._3 :^:t11._4 :^:t11._5 :^:t11._6 :^:t11._7 :^:t11._8 :^:t11._9 :^:t11._10 :^:t11._11 :^: KNil
def k12[M[_], A,B,C,D,E,F,G,H,I,J,K,L](t12: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L])) =t12._1 :^:t12._2 :^:t12._3 :^:t12._4 :^:t12._5 :^:t12._6 :^:t12._7 :^:t12._8 :^:t12._9 :^:t12._10 :^:t12._11 :^:t12._12 :^: KNil
def k13[M[_], A,B,C,D,E,F,G,H,I,J,K,L,N](t13: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N])) =t13._1 :^:t13._2 :^:t13._3 :^:t13._4 :^:t13._5 :^:t13._6 :^:t13._7 :^:t13._8 :^:t13._9 :^:t13._10 :^:t13._11 :^:t13._12 :^:t13._13 :^: KNil
def k14[M[_], A,B,C,D,E,F,G,H,I,J,K,L,N,O](t14: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N], M[O])) =t14._1 :^:t14._2 :^:t14._3 :^:t14._4 :^:t14._5 :^:t14._6 :^:t14._7 :^:t14._8 :^:t14._9 :^:t14._10 :^:t14._11 :^:t14._12 :^:t14._13 :^:t14._14 :^: KNil
def k15[M[_], A,B,C,D,E,F,G,H,I,J,K,L,N,O,P](t15: (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K], M[L], M[N], M[O], M[P])) =t15._1 :^:t15._2 :^:t15._3 :^:t15._4 :^:t15._5 :^:t15._6 :^:t15._7 :^:t15._8 :^:t15._9 :^:t15._10 :^:t15._11 :^:t15._12 :^:t15._13 :^:t15._14 :^:t15._15 :^: KNil
*/
private[sbt] def extendScoped(s1: Scoped, ss: Seq[Scoped]): Seq[AttributeKey[_]] = s1.key +: ss.map(_.key)
}

View File

@ -1,6 +1,6 @@
package sbt
import Project._
import Def.{displayFull,displayMasked,ScopedKey}
import java.net.URI
import TestBuild._
import complete._
@ -10,7 +10,7 @@ package sbt
import Prop._
import Arbitrary.arbBool
/** Tests that the scoped key parser in Act can correctly parse a ScopedKey converted by Project.show*Key.
/** Tests that the scoped key parser in Act can correctly parse a ScopedKey converted by Def.show*Key.
* This includes properly resolving omitted components.*/
object ParseKey extends Properties("Key parser test")
{
@ -24,9 +24,9 @@ object ParseKey extends Properties("Key parser test")
import skm.{structure, key, mask}
val expected = resolve(structure, key, mask)
val string = Project.displayMasked(key, mask)
val string = displayMasked(key, mask)
("Key: " + Project.displayFull(key)) |:
("Key: " + displayFull(key)) |:
parseExpected(structure, string, expected, mask)
}
@ -35,9 +35,9 @@ object ParseKey extends Properties("Key parser test")
import skm.{structure, key}
val mask = skm.mask.copy(project = false)
val string = Project.displayMasked(key, mask)
val string = displayMasked(key, mask)
("Key: " + Project.displayFull(key)) |:
("Key: " + displayFull(key)) |:
("Mask: " + mask) |:
("Current: " + structure.current) |:
parse(structure, string) {
@ -50,9 +50,9 @@ object ParseKey extends Properties("Key parser test")
forAllNoShrink(structureDefinedKey) { (skm: StructureKeyMask) =>
import skm.{structure, key}
val mask = skm.mask.copy(task = false)
val string = Project.displayMasked(key, mask)
val string = displayMasked(key, mask)
("Key: " + Project.displayFull(key)) |:
("Key: " + displayFull(key)) |:
("Mask: " + mask) |:
parse(structure, string) {
case Left(err) => false
@ -64,10 +64,10 @@ object ParseKey extends Properties("Key parser test")
forAllNoShrink(structureDefinedKey) { (skm: StructureKeyMask) =>
import skm.{structure, key}
val mask = ScopeMask(config = false)
val string = Project.displayMasked(key, mask)
val string = displayMasked(key, mask)
val resolvedConfig = Resolve.resolveConfig(structure.extra, key.key, mask)(key.scope).config
("Key: " + Project.displayFull(key)) |:
("Key: " + displayFull(key)) |:
("Mask: " + mask) |:
("Expected configuration: " + resolvedConfig.map(_.name)) |:
parse(structure, string) {
@ -88,7 +88,7 @@ object ParseKey extends Properties("Key parser test")
ScopedKey(Resolve(structure.extra, Select(structure.current), key.key, mask)(key.scope), key.key)
def parseExpected(structure: Structure, s: String, expected: ScopedKey[_], mask: ScopeMask): Prop =
("Expected: " + Project.displayFull(expected)) |:
("Expected: " + displayFull(expected)) |:
("Mask: " + mask) |:
parse(structure, s) {
case Left(err) => false
@ -99,7 +99,7 @@ object ParseKey extends Properties("Key parser test")
{
val parser = makeParser(structure)
val parsed = DefaultParsers.result(parser, s).left.map(_().toString)
val showParsed = parsed.right.map(Project.displayFull)
val showParsed = parsed.right.map(displayFull)
("Key string: '" + s + "'") |:
("Parsed: " + showParsed) |:
("Structure: " + structure) |:
@ -108,7 +108,7 @@ object ParseKey extends Properties("Key parser test")
def genStructure(implicit genEnv: Gen[Env]): Gen[Structure] =
structureGenF { (scopes: Seq[Scope], env: Env, current: ProjectRef) =>
val settings = for(scope <- scopes; t <- env.tasks) yield Project.setting(ScopedKey(scope, t.key), Project.value(""))
val settings = for(scope <- scopes; t <- env.tasks) yield Def.setting(ScopedKey(scope, t.key), Def.value(""))
TestBuild.structure(env, settings, current)
}

View File

@ -1,6 +1,6 @@
package sbt
import Project._
import Def.{ScopedKey, Setting}
import Types.{const,idFun,some}
import complete.Parser
@ -184,7 +184,7 @@ object TestBuild
def structure(env: Env, settings: Seq[Setting[_]], current: ProjectRef): Structure =
{
implicit val display = Project.showRelativeKey(current, env.allProjects.size > 1)
implicit val display = Def.showRelativeKey(current, env.allProjects.size > 1)
val data = Project.makeSettings(settings, env.delegates, const(Nil))
val keys = data.allKeys( (s, key) => ScopedKey(s, key))
val keyMap = keys.map(k => (k.key.label, k.key)).toMap[String, AttributeKey[_]]

View File

@ -16,7 +16,7 @@ object Sbt extends Build
organization := "org.scala-sbt",
version := "0.13.0-SNAPSHOT",
publishArtifact in packageDoc := false,
scalaVersion := "2.9.2",
scalaVersion := "2.10.0-M5",
publishMavenStyle := false,
componentID := None,
crossPaths := false,
@ -96,7 +96,7 @@ object Sbt extends Build
// Includes API and Analyzer phases that extract source API and relationships.
lazy val compileInterfaceSub = baseProject(compilePath / "interface", "Compiler Interface") dependsOn(interfaceSub, ioSub % "test->test", logSub % "test->test", launchSub % "test->test") settings( compileInterfaceSettings : _*)
lazy val precompiled282 = precompiled("2.8.2")
lazy val precompiled2100 = precompiled("2.10.0-RC2")
lazy val precompiled292 = precompiled("2.9.2")
// Implements the core functionality of detecting and propagating changes incrementally.
// Defines the data structures for representing file fingerprints and relationships and the overall source analysis
@ -132,7 +132,7 @@ object Sbt extends Build
// Strictly for bringing implicits and aliases from subsystems into the top-level sbt namespace through a single package object
// technically, we need a dependency on all of mainSub's dependencies, but we don't do that since this is strictly an integration project
// with the sole purpose of providing certain identifiers without qualification (with a package object)
lazy val sbtSub = baseProject(sbtPath, "Simple Build Tool") dependsOn(mainSub, compileInterfaceSub, precompiled282, precompiled2100, scriptedSbtSub % "test->test") settings(sbtSettings : _*)
lazy val sbtSub = baseProject(sbtPath, "Simple Build Tool") dependsOn(mainSub, compileInterfaceSub, precompiled282, precompiled292, scriptedSbtSub % "test->test") settings(sbtSettings : _*)
/* Nested subproject paths */
def sbtPath = file("sbt")
@ -249,5 +249,10 @@ object Sbt extends Build
libraryDependencies <+= scalaVersion( "org.scala-lang" % "scala-compiler" % _ % "test"),
unmanagedJars in Test <<= (packageSrc in compileInterfaceSub in Compile).map(x => Seq(x).classpath)
)
def precompiled(scalav: String): Project = baseProject(compilePath / "interface", "Precompiled " + scalav.replace('.', '_')) dependsOn(interfaceSub) settings(scalaVersion := scalav) settings(precompiledSettings : _*)
def precompiled(scalav: String): Project = baseProject(compilePath / "interface", "Precompiled " + scalav.replace('.', '_')) dependsOn(interfaceSub) settings(precompiledSettings : _*) settings(
scalaVersion <<= (scalaVersion in ThisBuild) { sbtScalaV =>
assert(sbtScalaV != scalav, "Precompiled compiler interface cannot have the same Scala version (" + scalav + ") as sbt.")
scalav
}
)
}

View File

@ -30,7 +30,7 @@ object Util
lazy val base: Seq[Setting[_]] = Seq(scalacOptions ++= Seq("-Xelide-below", "0"), projectComponent) ++ Licensed.settings
def testDependencies = libraryDependencies ++= Seq(
"org.scala-tools.testing" % "scalacheck_2.9.1" % "1.9" % "test",
"org.scalacheck" % "scalacheck_2.10.0-M5" % "1.10.0" % "test",
"org.scala-tools.testing" % "specs_2.9.1" % "1.6.9" % "test"
)

View File

@ -14,9 +14,9 @@ package object sbt extends sbt.std.TaskExtra with sbt.Types with sbt.ProcessExtr
@deprecated("Use InputKey, which is a drop-in replacement.", "0.11.1")
type ScopedInput[T] = InputKey[T]
type Setting[T] = Project.Setting[T]
type ScopedKey[T] = Project.ScopedKey[T]
type SettingsDefinition = Project.SettingsDefinition
type Setting[T] = Def.Setting[T]
type ScopedKey[T] = Def.ScopedKey[T]
type SettingsDefinition = Def.SettingsDefinition
type File = java.io.File
type URI = java.net.URI
type URL = java.net.URL

View File

@ -3,7 +3,7 @@
*/
package sbt
import Project.Initialize
import Def.Initialize
import Keys._
import classpath.ClasspathUtilities
import java.lang.reflect.Method

View File

@ -227,9 +227,8 @@ final class Execute[A[_] <: AnyRef](checkCycles: Boolean, triggers: Triggers[A])
def submit[T]( node: A[T] )(implicit strategy: Strategy)
{
val v = viewCache(node)
val rs = v.mixedIn transform getResult
val ud = v.uniformIn.map(getResult.apply[v.Uniform])
strategy.submit( node, () => work(node, v.work(rs, ud)) )
val rs = v.alist.transform(v.in, getResult)
strategy.submit( node, () => work(node, v.work(rs)) )
}
/** Evaluates the computation 'f' for 'node'.
* This returns a Completed instance, which contains the post-processing to perform after the result is retrieved from the Strategy.*/
@ -254,7 +253,7 @@ final class Execute[A[_] <: AnyRef](checkCycles: Boolean, triggers: Triggers[A])
def addCaller[T](caller: A[T], target: A[T]): Unit = callers.getOrUpdate(target, IDSet.create[A[T]]) += caller
def dependencies(node: A[_]): Iterable[A[_]] = dependencies(viewCache(node))
def dependencies(v: Node[A, _]): Iterable[A[_]] = (v.uniformIn ++ v.mixedIn.toList).filter(dep => view.inline(dep).isEmpty)
def dependencies(v: Node[A, _]): Iterable[A[_]] = v.alist.toList(v.in).filter(dep => view.inline(dep).isEmpty)
def runBefore(node: A[_]): Seq[A[_]] = getSeq(triggers.runBefore, node)
def triggeredBy(node: A[_]): Seq[A[_]] = getSeq(triggers.injectFor, node)

View File

@ -6,18 +6,15 @@ package sbt
import Types._
/** Represents a task node in a format understood by the task evaluation engine Execute.
* Heterogenous inputs (Mixed, tuple) and homogeneous (Uniform, sequence) are defined and consumed separately.
*
* @tparam A the task type
* @tparam A the task type constructor
* @tparam T the type computed by this node */
trait Node[A[_], T]
{
type Mixed <: HList
type Uniform
val mixedIn: KList[A, Mixed]
val uniformIn: Seq[A[Uniform]]
type K[L[x]]
val in: K[A]
val alist: AList[K]
/** Computes the result of this task given the results from the inputs. */
def work(mixed: KList[Result, Mixed], uniform: Seq[Result[Uniform]]): Either[A[T], T]
def work(inputs: K[Result]): Either[A[T], T]
}

View File

@ -1,163 +0,0 @@
/* sbt -- Simple Build Tool
* Copyright 2010 Mark Harrah
*/
package sbt
import Types._
import Task._
import Execute._
sealed trait Task[+T]
sealed case class Pure[+T](eval: () => T) extends Task[T]
final case class Mapped[+T, In <: HList](in: Tasks[In], f: Results[In] => T) extends Task[T]
final case class MapAll[+T, In <: HList](in: Tasks[In], f: In => T) extends Task[T]
final case class FlatMapAll[+T, In <: HList](in: Tasks[In], f: In => Task[T]) extends Task[T]
final case class MapFailure[+T, In <: HList](in: Tasks[In], f: Seq[Incomplete] => T) extends Task[T]
final case class FlatMapFailure[+T, In <: HList](in: Tasks[In], f: Seq[Incomplete] => Task[T]) extends Task[T]
final case class FlatMapped[+T, In <: HList](in: Tasks[In], f: Results[In] => Task[T]) extends Task[T]
final case class DependsOn[+T](in: Task[T], deps: Seq[Task[_]]) extends Task[T]
final case class Join[+T, U](in: Seq[Task[U]], f: Seq[U] => Either[Task[T], T]) extends Task[T] { type Uniform = U }
trait MultiInTask[In <: HList]
{
def flatMap[T](f: In => Task[T]): Task[T]
def flatMapR[T](f: Results[In] => Task[T]): Task[T]
def mapH[T](f: In => T): Task[T]
def mapR[T](f: Results[In] => T): Task[T]
def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T]
def mapFailure[T](f: Seq[Incomplete] => T): Task[T]
}
trait SingleInTask[S]
{
def flatMapR[T](f: Result[S] => Task[T]): Task[T]
def flatMap[T](f: S => Task[T]): Task[T]
def map[T](f: S => T): Task[T]
def mapR[T](f: Result[S] => T): Task[T]
def flatFailure[T](f: Incomplete => Task[T]): Task[T]
def mapFailure[T](f: Incomplete => T): Task[T]
def dependsOn(tasks: Task[_]*): Task[S]
}
trait ForkTask[S, CC[_]]
{
def fork[T](f: S => T): CC[Task[T]]
}
trait JoinTask[S, CC[_]]
{
def join: Task[CC[S]]
def reduced(f: (S,S) => S): Task[S]
}
object Task
{
type Tasks[HL <: HList] = KList[Task, HL]
type Results[HL <: HList] = KList[Result, HL]
def pure[T](f: => T): Task[T] = toPure(f _)
def pure[T](name: String, f: => T): Task[T] = new Pure(f _) { override def toString = name }
implicit def toPure[T](f: () => T): Task[T] = new Pure(f)
implicit def pureTasks[S](in: Seq[S]): Seq[Task[S]] = in.map(s => pure(s))
implicit def toTasks[S](in: Seq[() => S]): Seq[Task[S]] = in.map(toPure)
implicit def iterableTask[S](in: Seq[S]): ForkTask[S, Seq] = new ForkTask[S, Seq] {
def fork[T](f: S => T): Seq[Task[T]] = in.map(x => pure(x) map f)
}
implicit def pureJoin[S](in: Seq[S]): JoinTask[S, Seq] = joinTasks(pureTasks(in))
implicit def joinTasks[S](in: Seq[Task[S]]): JoinTask[S, Seq] = new JoinTask[S, Seq] {
def join: Task[Seq[S]] = new Join(in, (s: Seq[S]) => Right(s) )
//def join[T](f: Iterable[S] => T): Task[Iterable[T]] = new MapAll( MList.fromTCList[Task](in), ml => f(ml.toList))
//def joinR[T](f: Iterable[Result[S]] => T): Task[Iterable[Result[T]]] = new Mapped( MList.fromTCList[Task](in), ml => f(ml.toList))
def reduced(f: (S,S) => S): Task[S] = Task.reduced(in.toIndexedSeq, f)
}
implicit def multInputTask[In <: HList](tasks: Tasks[In]): MultiInTask[In] = new MultiInTask[In] {
def flatMap[T](f: In => Task[T]): Task[T] = new FlatMapAll(tasks, f)
def flatMapR[T](f: Results[In] => Task[T]): Task[T] = new FlatMapped(tasks, f)
def mapH[T](f: In => T): Task[T] = new MapAll(tasks, f)
def mapR[T](f: Results[In] => T): Task[T] = new Mapped(tasks, f)
def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T] = new FlatMapFailure(tasks, f)
def mapFailure[T](f: Seq[Incomplete] => T): Task[T] = new MapFailure(tasks, f)
}
implicit def singleInputTask[S](in: Task[S]): SingleInTask[S] = new SingleInTask[S] {
type HL = S :+: HNil
private val ml = in :^: KNil
private def headM = (_: Results[HL]).combine.head
private def headH = (_: HL).head
private def headS = (_: Seq[Incomplete]).head
def flatMapR[T](f: Result[S] => Task[T]): Task[T] = new FlatMapped[T, HL](ml, f headM)
def flatMap[T](f: S => Task[T]): Task[T] = new FlatMapAll(ml, f headH)
def map[T](f: S => T): Task[T] = new MapAll(ml, f headH)
def mapR[T](f: Result[S] => T): Task[T] = new Mapped[T, HL](ml, f headM)
def flatFailure[T](f: Incomplete => Task[T]): Task[T] = new FlatMapFailure(ml, f headS)
def mapFailure[T](f: Incomplete => T): Task[T] = new MapFailure(ml, f headS)
def dependsOn(tasks: Task[_]*): Task[S] = new DependsOn(in, tasks)
}
implicit val taskToNode = new NodeView[Task] {
def inline[T](a: Task[T]): Option[() => T] = None
def apply[T](t: Task[T]): Node[Task, T] = t match {
case Pure(eval) => toNode[T, HNil](KNil, _ => Right(eval()) )
case Mapped(in, f) => toNode(in, right f )
case MapAll(in, f) => toNode[T, in.Raw](in, right (f compose allM) )
case MapFailure(in, f) => toNode[T, in.Raw](in, right (f compose failuresM))
case FlatMapped(in, f) => toNode(in, left f )
case FlatMapAll(in, f) => toNode[T, in.Raw](in, left (f compose allM) )
case FlatMapFailure(in, f) => toNode[T, in.Raw](in, left (f compose failuresM))
case DependsOn(in, tasks) => join[T, Any](tasks, (_: Seq[Result[_]]) => Left(in))
case j@ Join(in, f) => join[T, j.Uniform](in, f compose all)
}
}
def join[T, D](tasks: Seq[Task[D]], f: Seq[Result[D]] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] {
type Mixed = HNil
val mixedIn = KNil
type Uniform = D
val uniformIn = tasks
def work(mixed: Results[HNil], uniform: Seq[Result[Uniform]]) = {
val inc = failures(uniform)
if(inc.isEmpty) f(uniform) else throw Incomplete(None, causes = inc)
}
}
def toNode[T, In <: HList](in: Tasks[In], f: Results[In] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] {
type Mixed = In
val mixedIn = in
type Uniform = Nothing
val uniformIn = Nil
def work(results: Results[In], units: Seq[Result[Uniform]]) = f(results)
}
def allM[In <: HList]: Results[In] => In = in =>
{
val incs = failuresM(in)
if(incs.isEmpty) in.down(Result.tryValue) else throw Incomplete(None, causes = incs)
}
def all[D]: Seq[Result[D]] => Seq[D] = in =>
{
val incs = failures(in)
if(incs.isEmpty) in.map(Result.tryValue.apply[D]) else throw Incomplete(None, causes = incs)
}
def failuresM[In <: HList]: Results[In] => Seq[Incomplete] = x => failures[Any](x.toList)
def failures[A]: Seq[Result[A]] => Seq[Incomplete] = _.collect { case Inc(i) => i }
def run[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): Result[T] =
{
val (service, shutdown) = CompletionService[Task[_], Completed](maxWorkers)
val x = new Execute[Task](checkCycles, Execute.noTriggers)(taskToNode)
try { x.run(root)(service) } finally { shutdown() }
}
def tryRun[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): T =
run(root, checkCycles, maxWorkers) match {
case Value(v) => v
case Inc(i) => throw i
}
def reduced[S](i: IndexedSeq[Task[S]], f: (S, S) => S): Task[S] =
i match
{
case Seq() => error("Cannot reduce empty sequence")
case Seq(x) => x
case Seq(x, y) => reducePair(x, y, f)
case z =>
val (a, b) = i.splitAt(i.size / 2)
reducePair( reduced(a, f), reduced(b, f), f )
}
def reducePair[S](a: Task[S], b: Task[S], f: (S, S) => S): Task[S] =
(a :^: b :^: KNil) mapH { case x :+: y :+: HNil => f(x,y) }
}

View File

@ -1,21 +0,0 @@
/* sbt -- Simple Build Tool
* Copyright 2009 Mark Harrah
*/
package sbt
import org.scalacheck._
import Gen.choose
object TaskGen
{
// upper bounds to make the tests finish in reasonable time
val MaxTasks = 100
val MaxWorkers = 29
val MaxJoin = 20
val MaxTasksGen = choose(0, MaxTasks)
val MaxWorkersGen = choose(1, MaxWorkers)
val MaxJoinGen = choose(0, MaxJoin)
val TaskListGen = MaxTasksGen.flatMap(size => Gen.listOfN(size, Arbitrary.arbInt.arbitrary))
}

View File

@ -1,61 +0,0 @@
/* sbt -- Simple Build Tool
* Copyright 2010 Mark Harrah
*/
package sbt
import Types._
import Task._
import Execute._
object Test
{
val a = pure(3)
val b = pure[Boolean](error("test"))
val b2 = pure(true)
val c = pure("asdf")
val i3 = a :^: b :^: c :^: KNil
val i32 = a :^: b2 :^: c :^: KNil
val fh= (_: Int :+: Boolean :+: String :+: HNil) match
{ case aa :+: bb :+: cc :+: HNil => aa + " " + bb + " " + cc }
val h1 = i3 mapH fh
val h2 = i32 mapH fh
type Values = Results[i3.Raw]
val f: Values => Any = {
case Value(aa) :^: Value(bb) :^: Value(cc) :^: KNil => aa + " " + bb + " " + cc
case x =>
val cs = x.toList.collect { case Inc(x) => x } // workaround for double definition bug
throw Incomplete(None, causes = cs)
}
val d2 = i32 mapR f
val f2: Values => Task[Any] = {
case Value(aa) :^: Value(bb) :^: Value(cc) :^: KNil => new Pure(() => aa + " " + bb + " " + cc)
case x => d3
}
lazy val d = i3 flatMapR f2
val f3: Values => Task[Any] = {
case Value(aa) :^: Value(bb) :^: Value(cc) :^: KNil => new Pure(() => aa + " " + bb + " " + cc)
case x => d2
}
lazy val d3= i3 flatMapR f3
def d4(i: Int): Task[Int] = KNil flatMap { _ => val x = math.random; if(x < 0.01) pure(i); else d4(i+1) }
def go()
{
def run[T](root: Task[T]) =
println("Result : " + Task.run(root, true, 2))
run(a)
run(b)
run(b2)
run(c)
run(d)
run(d2)
run( d4(0) )
run(h1)
run(h2)
}
}

View File

@ -12,26 +12,25 @@ package sbt
/** Defines a task compuation*/
sealed trait Action[T]
/** A direct computation of a value.
* If `inline` is true, `f` will be evaluated on the scheduler thread without the overhead of normal scheduling when possible.
* This is intended as an optimization for already evaluated values or very short computations. */
final case class Pure[T](f: () => T, inline: Boolean) extends Action[T]
/** Applies a function to the result of evaluating a heterogeneous list of other tasks.*/
final case class Mapped[T, In <: HList](in: Tasks[In], f: Results[In] => T) extends Action[T]
final case class Mapped[T, K[L[x]]](in: K[Task], f: K[Result] => T, alist: AList[K]) extends Action[T]
/** Computes another task to evaluate based on results from evaluating other tasks.*/
final case class FlatMapped[T, In <: HList](in: Tasks[In], f: Results[In] => Task[T]) extends Action[T]
final case class FlatMapped[T, K[L[x]]](in: K[Task], f: K[Result] => Task[T], alist: AList[K]) extends Action[T]
/** A computation `in` that requires other tasks `deps` to be evaluated first.*/
final case class DependsOn[T](in: Task[T], deps: Seq[Task[_]]) extends Action[T]
/** A computation that operates on the results of a homogeneous list of other tasks.
* It can either return another task to be evaluated or the final value.*/
final case class Join[T, U](in: Seq[Task[U]], f: Seq[Result[U]] => Either[Task[T], T]) extends Action[T]
object Task
{
type Tasks[HL <: HList] = KList[Task, HL]
type Results[HL <: HList] = KList[Result, HL]
}
/** Combines metadata `info` and a computation `work` to define a task. */
final case class Task[T](info: Info[T], work: Action[T])
{
@ -42,6 +41,7 @@ final case class Task[T](info: Info[T], work: Action[T])
def tagw(tags: (Tag, Int)*): Task[T] = copy(info = info.set(tagsKey, info.get(tagsKey).getOrElse(Map.empty) ++ tags ))
def tags: TagMap = info get tagsKey getOrElse Map.empty
}
/** Used to provide information about a task, such as the name, description, and tags for controlling concurrent execution.
* @param attributes Arbitrary user-defined key/value pairs describing this task
* @param post a transformation that takes the result of evaluating this task and produces user-defined key/value pairs. */

View File

@ -6,7 +6,7 @@ package std
import Types._
import Task._
import TaskExtra.allM
import TaskExtra.{all,existToAny}
import Execute._
object Transform
@ -16,17 +16,15 @@ object Transform
implicit def to_~>| [K[_], V[_]](map: RMap[K,V]) : K ~>| V = new (K ~>| V) { def apply[T](k: K[T]): Option[V[T]] = map.get(k) }
def dummyMap[HL <: HList](dummies: KList[Task, HL])(inject: HL): Task ~>| Task =
final case class DummyTaskMap(mappings: List[TaskAndValue[_]]) {
def ::[T](tav: (Task[T], T)): DummyTaskMap = DummyTaskMap(new TaskAndValue(tav._1, tav._2) :: mappings)
}
final class TaskAndValue[T](val task: Task[T], val value: T)
def dummyMap(dummyMap: DummyTaskMap): Task ~>| Task =
{
val pmap = new DelegatingPMap[Task, Task](new collection.mutable.ListMap)
def loop[HL <: HList](ds: KList[Task, HL], vs: HL): Unit =
(ds, vs) match {
case (KCons(dh, dt), vh :+: vt) =>
pmap(dh) = fromDummyStrict(dh, vh)
loop(dt, vt)
case _ => ()
}
loop(dummies, inject)
def add[T](dummy: TaskAndValue[T]) { pmap(dummy.task) = fromDummyStrict(dummy.task, dummy.value) }
dummyMap.mappings.foreach(x => add(x))
pmap
}
@ -36,18 +34,18 @@ object Transform
def apply[T](in: Task[T]): Task[T] = map(in).getOrElse(in)
}
def apply[HL <: HList, Key](dummies: KList[Task, HL], injected: HL) =
def apply(dummies: DummyTaskMap) =
{
import System._
taskToNode( getOrId(dummyMap(dummies)(injected)) )
taskToNode( getOrId(dummyMap(dummies)) )
}
def taskToNode(pre: Task ~> Task): NodeView[Task] = new NodeView[Task] {
def apply[T](t: Task[T]): Node[Task, T] = pre(t).work match {
case Pure(eval, _) => toNode(KNil)( _ => Right(eval()) )
case Mapped(in, f) => toNode(in)( right f )
case FlatMapped(in, f) => toNode(in)( left f )
case DependsOn(in, deps) => toNode(KList.fromList(deps))( ((_:Any) => Left(in)) allM )
case Pure(eval, _) => uniform(Nil)( _ => Right(eval()) )
case m: Mapped[t, k] => toNode[t,k](m.in)( right m.f )( m.alist )
case m: FlatMapped[t, k] => toNode[t,k](m.in)( left m.f )( m.alist )
case DependsOn(in, deps) => uniform( existToAny(deps) )( const(Left(in)) all )
case Join(in, f) => uniform(in)(f)
}
def inline[T](t: Task[T]) = t.work match {
@ -56,18 +54,13 @@ object Transform
}
}
def uniform[T, D](tasks: Seq[Task[D]])(f: Seq[Result[D]] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] {
type Mixed = HNil
val mixedIn = KNil
type Uniform = D
val uniformIn = tasks
def work(mixed: Results[HNil], uniform: Seq[Result[Uniform]]) = f(uniform)
}
def toNode[T, In <: HList](in: Tasks[In])(f: Results[In] => Either[Task[T], T]): Node[Task, T] = new Node[Task, T] {
type Mixed = In
val mixedIn = in
type Uniform = Nothing
val uniformIn = Nil
def work(results: Results[In], units: Seq[Result[Uniform]]) = f(results)
def uniform[T, D](tasks: Seq[Task[D]])(f: Seq[Result[D]] => Either[Task[T], T]): Node[Task, T] =
toNode[T, ({ type l[L[x]] = List[L[D]] })#l]( tasks.toList )( f )( AList.seq[D] )
def toNode[T, k[L[x]]](inputs: k[Task])(f: k[Result] => Either[Task[T], T])(implicit a: AList[k]): Node[Task, T] = new Node[Task, T] {
type K[L[x]] = k[L]
val in = inputs
val alist = a
def work(results: K[Result]) = f(results)
}
}

View File

@ -8,15 +8,16 @@ package std
import Task._
import java.io.{BufferedInputStream, BufferedReader, File, InputStream}
sealed trait MultiInTask[In <: HList]
sealed trait MultiInTask[K[L[x]]]
{
def flatMap[T](f: In => Task[T]): Task[T]
def flatMapR[T](f: Results[In] => Task[T]): Task[T]
def map[T](f: In => T): Task[T]
def mapR[T](f: Results[In] => T): Task[T]
def flatMap[T](f: K[Id] => Task[T]): Task[T]
def flatMapR[T](f: K[Result] => Task[T]): Task[T]
def map[T](f: K[Id] => T): Task[T]
def mapR[T](f: K[Result] => T): Task[T]
def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T]
def mapFailure[T](f: Seq[Incomplete] => T): Task[T]
}
sealed trait SingleInTask[S]
{
def flatMapR[T](f: Result[S] => Task[T]): Task[T]
@ -77,49 +78,45 @@ trait TaskExtra
final def nop: Task[Unit] = constant( () )
final def constant[T](t: T): Task[T] = task(t)
final implicit def t2ToMulti[A,B](t: (Task[A],Task[B])) = multInputTask(t._1 :^: t._2 :^: KNil)
final implicit def f2ToHfun[A,B,R](f: (A,B) => R): (A :+: B :+: HNil => R) = { case a :+: b :+: HNil => f(a,b) }
final implicit def t3ToMulti[A,B,C](t: (Task[A],Task[B],Task[C])) = multInputTask(t._1 :^: t._2 :^: t._3 :^: KNil)
final implicit def f3ToHfun[A,B,C,R](f: (A,B,C) => R): (A :+: B :+: C :+: HNil => R) = { case a :+: b :+: c :+: HNil => f(a,b,c) }
final implicit def actionToTask[T](a: Action[T]): Task[T] = Task(Info(), a)
final def task[T](f: => T): Task[T] = toTask(f _)
final implicit def toTask[T](f: () => T): Task[T] = new Pure(f, false)
final def inlineTask[T](value: T): Task[T] = new Pure(() => value, true)
final implicit def upcastTask[A >: B, B](t: Task[B]): Task[A] = t map { x => x : B }
final implicit def upcastTask[A >: B, B](t: Task[B]): Task[A] = t map { x => x : A }
final implicit def toTasks[S](in: Seq[() => S]): Seq[Task[S]] = in.map(toTask)
final implicit def iterableTask[S](in: Seq[S]): ForkTask[S, Seq] = new ForkTask[S, Seq] {
def fork[T](f: S => T): Seq[Task[T]] = in.map(x => task(f(x)))
def tasks: Seq[Task[S]] = fork(idFun)
}
final implicit def joinAnyTasks(in: Seq[Task[_]]): JoinTask[Any, Seq] = joinTasks[Any](in map (x => x: Task[Any]))
import TaskExtra.{allM, anyFailM, existToAny, failM, successM}
final implicit def joinAnyTasks(in: Seq[Task[_]]): JoinTask[Any, Seq] = joinTasks[Any]( existToAny(in) )
final implicit def joinTasks[S](in: Seq[Task[S]]): JoinTask[S, Seq] = new JoinTask[S, Seq] {
def join: Task[Seq[S]] = new Join(in, (s: Seq[Result[S]]) => Right(TaskExtra.all(s)) )
def reduced(f: (S,S) => S): Task[S] = TaskExtra.reduced(in.toIndexedSeq, f)
}
import TaskExtra.{allM, anyFailM, failM, successM}
final implicit def multInputTask[In <: HList](tasks: Tasks[In]): MultiInTask[In] = new MultiInTask[In] {
def flatMapR[T](f: Results[In] => Task[T]): Task[T] = new FlatMapped(tasks, f)
def flatMap[T](f: In => Task[T]): Task[T] = flatMapR(f compose allM)
def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T] = flatMapR(f compose anyFailM)
def mapR[T](f: Results[In] => T): Task[T] = new Mapped(tasks, f)
def map[T](f: In => T): Task[T] = mapR(f compose allM)
def mapFailure[T](f: Seq[Incomplete] => T): Task[T] = mapR(f compose anyFailM)
final implicit def multT2Task[A,B](in: (Task[A], Task[B])) = multInputTask[({ type l[L[x]] = (L[A], L[B]) })#l](in)(AList.tuple2[A,B])
final implicit def multInputTask[K[L[X]]](tasks: K[Task])(implicit a: AList[K]): MultiInTask[K] = new MultiInTask[K] {
def flatMapR[T](f: K[Result] => Task[T]): Task[T] = new FlatMapped[T,K](tasks, f, a)
def flatMap[T](f: K[Id] => Task[T]): Task[T] = new FlatMapped[T, K](tasks, f compose allM, a)
def flatFailure[T](f: Seq[Incomplete] => Task[T]): Task[T] = new FlatMapped[T,K](tasks, f compose anyFailM, a)
def mapR[T](f: K[Result] => T): Task[T] = new Mapped[T,K](tasks, f, a)
def map[T](f: K[Id] => T): Task[T] = new Mapped[T,K](tasks, f compose allM, a)
def mapFailure[T](f: Seq[Incomplete] => T): Task[T] = new Mapped[T,K](tasks, f compose anyFailM, a)
}
final implicit def singleInputTask[S](in: Task[S]): SingleInTask[S] = new SingleInTask[S] {
type HL = S :+: HNil
private val ml = in :^: KNil
private def headM = (_: Results[HL]).combine.head
type K[L[x]] = L[S]
private def ml = AList.single[S]
def flatMapR[T](f: Result[S] => Task[T]): Task[T] = new FlatMapped[T, HL](ml, f headM)
def mapR[T](f: Result[S] => T): Task[T] = new Mapped[T, HL](ml, f headM)
def flatMapR[T](f: Result[S] => Task[T]): Task[T] = new FlatMapped[T, K](in, f, ml)
def mapR[T](f: Result[S] => T): Task[T] = new Mapped[T, K](in, f, ml)
def dependsOn(tasks: Task[_]*): Task[S] = new DependsOn(in, tasks)
def flatMap[T](f: S => Task[T]): Task[T] = flatMapR(f compose successM)
@ -198,12 +195,13 @@ object TaskExtra extends TaskExtra
val (a, b) = i.splitAt(i.size / 2)
reducePair( reduced(a, f), reduced(b, f), f )
}
def reducePair[S](a: Task[S], b: Task[S], f: (S, S) => S): Task[S] =
(a :^: b :^: KNil) map { case x :+: y :+: HNil => f(x,y) }
def anyFailM[In <: HList]: Results[In] => Seq[Incomplete] = in =>
def reducePair[S](a: Task[S], b: Task[S], f: (S, S) => S): Task[S] =
multInputTask[({ type l[L[x]] = (L[S], L[S])})#l]((a,b))(AList.tuple2[S,S]) map f.tupled
def anyFailM[K[L[x]]](implicit a: AList[K]): K[Result] => Seq[Incomplete] = in =>
{
val incs = failuresM(in)
val incs = failuresM(a)(in)
if(incs.isEmpty) expectedFailure else incs
}
def failM[T]: Result[T] => Incomplete = { case Inc(i) => i; case x => expectedFailure }
@ -211,12 +209,12 @@ object TaskExtra extends TaskExtra
def expectedFailure = throw Incomplete(None, message = Some("Expected dependency to fail."))
def successM[T]: Result[T] => T = { case Inc(i) => throw i; case Value(t) => t }
def allM[In <: HList]: Results[In] => In = in =>
def allM[K[L[x]]](implicit a: AList[K]): K[Result] => K[Id] = in =>
{
val incs = failuresM(in)
if(incs.isEmpty) in.down(Result.tryValue) else throw incompleteDeps(incs)
val incs = failuresM(a)(in)
if(incs.isEmpty) a.transform(in, Result.tryValue) else throw incompleteDeps(incs)
}
def failuresM[In <: HList]: Results[In] => Seq[Incomplete] = x => failures[Any](x.toList)
def failuresM[K[L[x]]](implicit a: AList[K]): K[Result] => Seq[Incomplete] = x => failures[Any](a.toList(x))
def all[D](in: Seq[Result[D]]) =
{
@ -226,4 +224,6 @@ object TaskExtra extends TaskExtra
def failures[A](results: Seq[Result[A]]): Seq[Incomplete] = results.collect { case Inc(i) => i }
def incompleteDeps(incs: Seq[Incomplete]): Incomplete = Incomplete(None, causes = incs)
private[sbt] def existToAny(in: Seq[Task[_]]): Seq[Task[Any]] = in.asInstanceOf[Seq[Task[Any]]]
}

View File

@ -13,13 +13,13 @@ object ExecuteSpec extends Properties("Execute")
val iGen = Arbitrary.arbInt.arbitrary
property("evaluates simple task") = forAll(iGen, MaxWorkersGen) { (i: Int, workers: Int) =>
("Workers: " + workers) |:
checkResult(tryRun(pure(i), false, workers), i)
checkResult(tryRun(task(i), false, workers), i)
}
// no direct dependencies currently
/*property("evaluates simple static graph") = forAll(iGen, MaxWorkersGen) { (i: Int, workers: Int) =>
("Workers: " + workers) |:
{
def result = tryRun(Task(i) dependsOn(pure(false),pure("a")), false, workers)
def result = tryRun(Task(i) dependsOn(task(false),task("a")), false, workers)
checkResult(result, i)
}
}*/
@ -27,23 +27,23 @@ object ExecuteSpec extends Properties("Execute")
property("evaluates simple mapped task") = forAll(iGen, MaxTasksGen, MaxWorkersGen) { (i: Int, times: Int, workers: Int) =>
("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |:
{
def result = tryRun(pure(i).map(_*times), false, workers)
def result = tryRun(task(i).map(_*times), false, workers)
checkResult(result, i*times)
}
}
property("evaluates chained mapped task") = forAllNoShrink(iGen, MaxTasksGen, MaxWorkersGen) { (i: Int, times: Int, workers: Int) =>
("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |:
{
val initial = pure(0) map(identity[Int])
def task = ( initial /: (0 until times) )( (t,ignore) => t.map(_ + i))
checkResult(tryRun(task, false, workers), i*times)
val initial = task(0) map(identity[Int])
def t = ( initial /: (0 until times) )( (t,ignore) => t.map(_ + i))
checkResult(tryRun(t, false, workers), i*times)
}
}
property("evaluates simple bind") = forAll(iGen, MaxTasksGen, MaxWorkersGen) { (i: Int, times: Int, workers: Int) =>
("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |:
{
def result = tryRun(pure(i).flatMap(x => pure(x*times)), false, workers)
def result = tryRun(task(i).flatMap(x => task(x*times)), false, workers)
checkResult(result, i*times)
}
}

View File

@ -0,0 +1,33 @@
/* sbt -- Simple Build Tool
* Copyright 2009 Mark Harrah
*/
package sbt
import org.scalacheck._
import Gen.choose
object TaskGen extends std.TaskExtra
{
// upper bounds to make the tests finish in reasonable time
val MaxTasks = 100
val MaxWorkers = 29
val MaxJoin = 20
val MaxTasksGen = choose(0, MaxTasks)
val MaxWorkersGen = choose(1, MaxWorkers)
val MaxJoinGen = choose(0, MaxJoin)
val TaskListGen = MaxTasksGen.flatMap(size => Gen.listOfN(size, Arbitrary.arbInt.arbitrary))
def run[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): Result[T] =
{
val (service, shutdown) = CompletionService[Task[_], Completed](maxWorkers)
val dummies = std.Transform.DummyTaskMap(Nil)
val x = new Execute[Task](checkCycles, Execute.noTriggers)(std.Transform(dummies))
try { x.run(root)(service) } finally { shutdown() }
}
def tryRun[T](root: Task[T], checkCycles: Boolean, maxWorkers: Int): T =
run(root, checkCycles, maxWorkers) match {
case Value(v) => v
case Inc(i) => throw i
}
}

View File

@ -11,26 +11,26 @@ object TaskRunnerCircularTest extends Properties("TaskRunner Circular")
property("Allows references to completed tasks") = forAllNoShrink(MaxTasksGen, MaxWorkersGen) { allowedReference _ }
final def allowedReference(intermediate: Int, workers: Int) =
{
val top = pure("top", intermediate)
def iterate(task: Task[Int]): Task[Int] =
task flatMap { t =>
val top = task(intermediate).named("top")
def iterate(tk: Task[Int]): Task[Int] =
tk flatMap { t =>
if(t <= 0)
top
else
iterate(pure((t-1).toString, t-1) )
iterate(task(t-1).named((t-1).toString) )
}
try { checkResult(tryRun(iterate(top), true, workers), intermediate) }
catch { case i: Incomplete if cyclic(i) => ("Unexpected cyclic exception: " + i) |: false }
}
final def checkCircularReferences(intermediate: Int, workers: Int) =
{
lazy val top = iterate(pure("bottom", intermediate), intermediate)
def iterate(task: Task[Int], i: Int): Task[Int] =
task flatMap { t =>
lazy val top = iterate(task(intermediate).named("bottom"), intermediate)
def iterate(tk: Task[Int], i: Int): Task[Int] =
tk flatMap { t =>
if(t <= 0)
top
else
iterate(pure((t-1).toString, t-1), i-1)
iterate(task(t-1).named((t-1).toString), i-1)
}
try { tryRun(top, true, workers); false }
catch { case i: Incomplete => cyclic(i) }

View File

@ -25,13 +25,13 @@ object TaskRunnerForkTest extends Properties("TaskRunner Fork")
}
def runDoubleJoin(a: Int, b: Int, workers: Int)
{
def inner(i: Int) = List.range(0, b).map(j => pure(j.toString, j)).join
def inner(i: Int) = List.range(0, b).map(j => task(j).named(j.toString)).join
tryRun( List.range(0,a).map(inner).join, false, workers)
}
property("fork and reduce") = forAll(TaskListGen, MaxWorkersGen) { (m: List[Int], workers: Int) =>
(!m.isEmpty) ==> {
val expected = m.reduceLeft(_+_)
checkResult(tryRun( m.reduced(_ + _), false, workers), expected)
checkResult(tryRun( m.tasks.reduced(_ + _), false, workers), expected)
}
}
}

View File

@ -0,0 +1,60 @@
/* sbt -- Simple Build Tool
* Copyright 2010 Mark Harrah
*/
package sbt
import Types._
import Task._
import Execute._
object Test extends std.TaskExtra
{
def t2[A, B](a: Task[A], b: Task[B]) = multInputTask[({type l[L[x]] = (L[A], L[B])})#l]((a, b))(AList.tuple2)
def t3[A, B, C](a: Task[A], b: Task[B], c: Task[C]) = multInputTask[({type l[L[x]] = (L[A], L[B], L[C])})#l]((a, b, c))(AList.tuple3)
val a = task(3)
val b = task[Boolean](error("test"))
val b2 = task(true)
val c = task("asdf")
val h1 = t3(a,b,c).map { case (aa,bb,cc) => aa + " " + bb + " " + cc }
val h2 = t3(a,b2,c).map { case (aa,bb,cc) => aa + " " + bb + " " + cc }
type Values = (Result[Int], Result[Boolean], Result[String])
val f: Values => Any = {
case (Value(aa), Value(bb), Value(cc)) => aa + " " + bb + " " + cc
case x =>
val cs = x.productIterator.toList.collect { case Inc(x) => x } // workaround for double definition bug
throw Incomplete(None, causes = cs)
}
val d2 = t3(a,b2,c) mapR f
val f2: Values => Task[Any] = {
case (Value(aa), Value(bb), Value(cc)) => task(aa + " " + bb + " " + cc)
case x => d3
}
lazy val d = t3(a,b,c) flatMapR f2
val f3: Values => Task[Any] = {
case (Value(aa), Value(bb), Value(cc)) => task(aa + " " + bb + " " + cc)
case x => d2
}
lazy val d3= t3(a,b,c) flatMapR f3
def d4(i: Int): Task[Int] = nop flatMap { _ => val x = math.random; if(x < 0.01) task(i); else d4(i+1) }
def go()
{
def run[T](root: Task[T]) =
println("Result : " + TaskGen.run(root, true, 2))
run(a)
run(b)
run(b2)
run(c)
run(d)
run(d2)
run( d4(0) )
run(h1)
run(h2)
}
}

View File

@ -24,11 +24,11 @@ object TaskRunnerCallTest extends Properties("TaskRunner Call")
(index, x1, x2) =>
{
if(index == i)
pure(x2)
task(x2)
else
iterate( (index+1, x2, x1+x2) )
}
def iterate(iteration: (Int,Int,Int)) = pure( iteration ) flatMap next.tupled
def iterate(iteration: (Int,Int,Int)) = task( iteration ) flatMap next.tupled
iterate( (1, 0, 1) )
}
final def fibDirect(i: Int): Int =

View File

@ -35,14 +35,14 @@ object TaskRunnerSortTest extends Properties("TaskRunnerSort")
final def sort(a: Seq[Int]): Task[Seq[Int]] =
{
if(a.length < 200)
pure(sortDirect(a))
task(sortDirect(a))
else
{
pure(a) flatMap { a =>
task(a) flatMap { a =>
val pivot = a(0)
val (lt,gte) = a.view.drop(1).partition(_ < pivot)
sort(lt) :^: sort(gte) :^: KNil mapH {
case l :+: g :+: HNil => l ++ List(pivot) ++ g
Test.t2(sort(lt), sort(gte)) map {
case (l, g) => l ++ List(pivot) ++ g
}
}
}

211
util/collection/AList.scala Normal file
View File

@ -0,0 +1,211 @@
package sbt
import Classes.Applicative
import Types._
/** An abstraction over (* -> *) -> * with the purpose of abstracting over arity abstractions like KList and TupleN
* as well as homogeneous sequences Seq[M[T]]. */
trait AList[K[L[x]] ]
{
def transform[M[_], N[_]](value: K[M], f: M ~> N): K[N]
def traverse[M[_], N[_], P[_]](value: K[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[K[P]]
def foldr[M[_], A](value: K[M], f: (M[_], A) => A, init: A): A
def toList[M[_]](value: K[M]): List[M[_]] = foldr[M, List[M[_]]](value, _ :: _, Nil)
def apply[M[_], C](value: K[M], f: K[Id] => C)(implicit a: Applicative[M]): M[C] =
a.map(f, traverse[M, M, Id](value, idK[M])(a))
}
object AList
{
type Empty = AList[({ type l[L[x]] = Unit})#l]
val empty: Empty = new Empty {
def transform[M[_], N[_]](in: Unit, f: M ~> N) = ()
def foldr[M[_], T](in: Unit, f: (M[_], T) => T, init: T) = init
override def apply[M[_], C](in: Unit, f: Unit => C)(implicit app: Applicative[M]): M[C] = app.pure( f( () ) )
def traverse[M[_], N[_], P[_]](in: Unit, f: M ~> (N P)#l)(implicit np: Applicative[N]): N[Unit] = np.pure( () )
}
type SeqList[T] = AList[({ type l[L[x]] = List[L[T]] })#l]
def seq[T]: SeqList[T] = new SeqList[T]
{
def transform[M[_], N[_]](s: List[M[T]], f: M ~> N) = s.map(f.fn[T])
def foldr[M[_], A](s: List[M[T]], f: (M[_], A) => A, init: A): A = (init /: s.reverse)( (t, m) => f(m,t))
override def apply[M[_], C](s: List[M[T]], f: List[T] => C)(implicit ap: Applicative[M]): M[C] =
{
def loop[V](in: List[M[T]], g: List[T] => V): M[V] =
in match {
case Nil => ap.pure(g(Nil))
case x :: xs =>
val h = (ts: List[T]) => (t: T) => g(t :: ts)
ap.apply( loop(xs, h), x )
}
loop(s, f)
}
def traverse[M[_], N[_], P[_]](s: List[M[T]], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[List[P[T]]] = ???
}
def klist[KL[M[_]] <: KList[M] { type Transform[N[_]] = KL[N] }]: AList[KL] = new AList[KL] {
def transform[M[_], N[_]](k: KL[M], f: M ~> N) = k.transform(f)
def foldr[M[_], T](k: KL[M], f: (M[_], T) => T, init: T): T = k.foldr(f, init)
override def apply[M[_], C](k: KL[M], f: KL[Id] => C)(implicit app: Applicative[M]): M[C] = k.apply(f)(app)
def traverse[M[_], N[_], P[_]](k: KL[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[KL[P]] = k.traverse[N,P](f)(np)
}
type Single[A] = AList[({ type l[L[x]] = L[A]})#l]
def single[A]: Single[A] = new Single[A] {
def transform[M[_], N[_]](a: M[A], f: M ~> N) = f(a)
def foldr[M[_], T](a: M[A], f: (M[_], T) => T, init: T): T = f(a, init)
def traverse[M[_], N[_], P[_]](a: M[A], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[P[A]] = f(a)
}
type ASplit[K[L[x]], B[x]] = AList[ ({ type l[L[x]] = K[ (L B)#l] })#l ]
def asplit[ K[L[x]], B[x] ](base: AList[K]): ASplit[K,B] = new ASplit[K, B]
{
type Split[ L[x] ] = K[ (L B)#l ]
def transform[M[_], N[_]](value: Split[M], f: M ~> N): Split[N] =
base.transform[(M B)#l, (N B)#l](value, nestCon[M,N,B](f))
def traverse[M[_], N[_], P[_]](value: Split[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[Split[P]] =
{
val g = nestCon[M, (N P)#l, B](f)
base.traverse[(M B)#l, N, (P B)#l](value, g)(np)
}
def foldr[M[_], A](value: Split[M], f: (M[_], A) => A, init: A): A =
base.foldr[(M B)#l, A](value, f, init)
}
// TODO: auto-generate
sealed trait T2K[A,B] { type l[L[x]] = (L[A], L[B]) }
type T2List[A,B] = AList[T2K[A,B]#l]
def tuple2[A, B]: T2List[A,B] = new T2List[A,B]
{
type T2[M[_]] = (M[A], M[B])
def transform[M[_], N[_]](t: T2[M], f: M ~> N): T2[N] = (f(t._1), f(t._2))
def foldr[M[_], T](t: T2[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, init))
def traverse[M[_], N[_], P[_]](t: T2[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[T2[P]] =
{
val g = (Tuple2.apply[P[A], P[B]] _).curried
np.apply( np.map(g, f(t._1)), f(t._2) )
}
}
sealed trait T3K[A,B,C] { type l[L[x]] = (L[A], L[B], L[C]) }
type T3List[A,B,C] = AList[T3K[A,B,C]#l]
def tuple3[A, B, C]: T3List[A,B,C] = new T3List[A,B,C]
{
type T3[M[_]] = (M[A], M[B], M[C])
def transform[M[_], N[_]](t: T3[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3))
def foldr[M[_], T](t: T3[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, init)))
def traverse[M[_], N[_], P[_]](t: T3[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[T3[P]] =
{
val g = (Tuple3.apply[P[A],P[B],P[C]] _).curried
np.apply( np.apply( np.map(g, f(t._1)), f(t._2) ), f(t._3) )
}
}
sealed trait T4K[A,B,C,D] { type l[L[x]] = (L[A], L[B], L[C], L[D]) }
type T4List[A,B,C,D] = AList[T4K[A,B,C,D]#l]
def tuple4[A, B, C, D]: T4List[A,B,C,D] = new T4List[A,B,C,D]
{
type T4[M[_]] = (M[A], M[B], M[C], M[D])
def transform[M[_], N[_]](t: T4[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4))
def foldr[M[_], T](t: T4[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, init))))
def traverse[M[_], N[_], P[_]](t: T4[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[T4[P]] =
{
val g = (Tuple4.apply[P[A], P[B], P[C], P[D]] _).curried
np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4))
}
}
sealed trait T5K[A,B,C,D,E] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E]) }
type T5List[A,B,C,D,E] = AList[T5K[A,B,C,D,E]#l]
def tuple5[A, B, C, D, E]: T5List[A,B,C,D,E] = new T5List[A,B,C,D,E] {
type T5[M[_]] = (M[A], M[B], M[C], M[D], M[E])
def transform[M[_], N[_]](t: T5[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5))
def foldr[M[_], T](t: T5[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, init)))))
def traverse[M[_], N[_], P[_]](t: T5[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[T5[P]] =
{
val g = (Tuple5.apply[P[A],P[B],P[C],P[D],P[E]] _ ).curried
np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5) )
}
}
sealed trait T6K[A,B,C,D,E,F] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F]) }
type T6List[A,B,C,D,E,F] = AList[T6K[A,B,C,D,E,F]#l]
def tuple6[A, B, C, D, E, F]: T6List[A,B,C,D,E,F] = new T6List[A,B,C,D,E,F] {
type T6[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F])
def transform[M[_], N[_]](t: T6[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6))
def foldr[M[_], T](t: T6[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, init))))))
def traverse[M[_], N[_], P[_]](t: T6[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[T6[P]] =
{
val g = (Tuple6.apply[P[A],P[B],P[C],P[D],P[E],P[F]] _ ).curried
np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6))
}
}
sealed trait T7K[A,B,C,D,E,F,G] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F], L[G]) }
type T7List[A,B,C,D,E,F,G] = AList[T7K[A,B,C,D,E,F,G]#l]
def tuple7[A,B,C,D,E,F,G]: T7List[A,B,C,D,E,F,G] = new T7List[A,B,C,D,E,F,G] {
type T7[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G])
def transform[M[_], N[_]](t: T7[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6), f(t._7))
def foldr[M[_], T](t: T7[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, f(t._7, init)))))))
def traverse[M[_], N[_], P[_]](t: T7[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[T7[P]] =
{
val g = (Tuple7.apply[P[A],P[B],P[C],P[D],P[E],P[F],P[G]] _ ).curried
np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6)), f(t._7))
}
}
sealed trait T8K[A,B,C,D,E,F,G,H] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F], L[G], L[H]) }
type T8List[A,B,C,D,E,F,G,H] = AList[T8K[A,B,C,D,E,F,G,H]#l]
def tuple8[A,B,C,D,E,F,G,H]: T8List[A,B,C,D,E,F,G,H] = new T8List[A,B,C,D,E,F,G,H] {
type T8[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H])
def transform[M[_], N[_]](t: T8[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6), f(t._7), f(t._8))
def foldr[M[_], T](t: T8[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, f(t._7, f(t._8, init))))))))
def traverse[M[_], N[_], P[_]](t: T8[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[T8[P]] =
{
val g = (Tuple8.apply[P[A],P[B],P[C],P[D],P[E],P[F],P[G],P[H]] _ ).curried
np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6)), f(t._7)), f(t._8))
}
}
sealed trait T9K[A,B,C,D,E,F,G,H,I] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F], L[G], L[H], L[I]) }
type T9List[A,B,C,D,E,F,G,H,I] = AList[T9K[A,B,C,D,E,F,G,H,I]#l]
def tuple9[A,B,C,D,E,F,G,H,I]: T9List[A,B,C,D,E,F,G,H,I] = new T9List[A,B,C,D,E,F,G,H,I] {
type T9[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I])
def transform[M[_], N[_]](t: T9[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6), f(t._7), f(t._8), f(t._9))
def foldr[M[_], T](t: T9[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, f(t._7, f(t._8, f(t._9, init)))))))))
def traverse[M[_], N[_], P[_]](t: T9[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[T9[P]] =
{
val g = (Tuple9.apply[P[A],P[B],P[C],P[D],P[E],P[F],P[G],P[H],P[I]] _ ).curried
np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6)), f(t._7)), f(t._8)), f(t._9))
}
}
sealed trait T10K[A,B,C,D,E,F,G,H,I,J] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F], L[G], L[H], L[I], L[J]) }
type T10List[A,B,C,D,E,F,G,H,I,J] = AList[T10K[A,B,C,D,E,F,G,H,I,J]#l]
def tuple10[A,B,C,D,E,F,G,H,I,J]: T10List[A,B,C,D,E,F,G,H,I,J] = new T10List[A,B,C,D,E,F,G,H,I,J] {
type T10[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J])
def transform[M[_], N[_]](t: T10[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6), f(t._7), f(t._8), f(t._9), f(t._10))
def foldr[M[_], T](t: T10[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, f(t._7, f(t._8, f(t._9, f(t._10, init))))))))))
def traverse[M[_], N[_], P[_]](t: T10[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[T10[P]] =
{
val g = (Tuple10.apply[P[A],P[B],P[C],P[D],P[E],P[F],P[G],P[H],P[I],P[J]] _ ).curried
np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6)), f(t._7)), f(t._8)), f(t._9)), f(t._10))
}
}
sealed trait T11K[A,B,C,D,E,F,G,H,I,J,K] { type l[L[x]] = (L[A], L[B], L[C], L[D], L[E], L[F], L[G], L[H], L[I], L[J], L[K]) }
type T11List[A,B,C,D,E,F,G,H,I,J,K] = AList[T11K[A,B,C,D,E,F,G,H,I,J,K]#l]
def tuple11[A,B,C,D,E,F,G,H,I,J,K]: T11List[A,B,C,D,E,F,G,H,I,J,K] = new T11List[A,B,C,D,E,F,G,H,I,J,K] {
type T11[M[_]] = (M[A], M[B], M[C], M[D], M[E], M[F], M[G], M[H], M[I], M[J], M[K])
def transform[M[_], N[_]](t: T11[M], f: M ~> N) = (f(t._1), f(t._2), f(t._3), f(t._4), f(t._5), f(t._6), f(t._7), f(t._8), f(t._9), f(t._10), f(t._11))
def foldr[M[_], T](t: T11[M], f: (M[_], T) => T, init: T): T = f(t._1, f(t._2, f(t._3, f(t._4, f(t._5, f(t._6, f(t._7, f(t._8, f(t._9, f(t._10, f(t._11,init)))))))))))
def traverse[M[_], N[_], P[_]](t: T11[M], f: M ~> (N P)#l)(implicit np: Applicative[N]): N[T11[P]] =
{
val g = (Tuple11.apply[P[A],P[B],P[C],P[D],P[E],P[F],P[G],P[H],P[I],P[J],P[K]] _ ).curried
np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.apply( np.map(g, f(t._1)), f(t._2)), f(t._3)), f(t._4)), f(t._5)), f(t._6)), f(t._7)), f(t._8)), f(t._9)), f(t._10)), f(t._11))
}
}
}

View File

@ -0,0 +1,27 @@
package sbt
object Classes
{
trait Applicative[M[_]]
{
def apply[S,T](f: M[S => T], v: M[S]): M[T]
def pure[S](s: => S): M[S]
def map[S, T](f: S => T, v: M[S]): M[T]
}
trait Monad[M[_]] extends Applicative[M]
{
def flatten[T](m: M[M[T]]): M[T]
}
implicit val optionMonad: Monad[Option] = new Monad[Option] {
def apply[S,T](f: Option[S => T], v: Option[S]) = (f, v) match { case (Some(fv), Some(vv)) => Some(fv(vv)); case _ => None }
def pure[S](s: => S) = Some(s)
def map[S, T](f: S => T, v: Option[S]) = v map f
def flatten[T](m: Option[Option[T]]): Option[T] = m.flatten
}
implicit val listMonad: Monad[List] = new Monad[List] {
def apply[S,T](f: List[S => T], v: List[S]) = for(fv <- f; vv <- v) yield fv(vv)
def pure[S](s: => S) = s :: Nil
def map[S, T](f: S => T, v: List[S]) = v map f
def flatten[T](m: List[List[T]]): List[T] = m.flatten
}
}

View File

@ -3,7 +3,7 @@ package sbt
import java.lang.Runnable
import java.util.concurrent.{atomic, Executor, LinkedBlockingQueue}
import atomic.{AtomicBoolean, AtomicInteger}
import Types.{:+:, Id}
import Types.{:+:, ConstK, Id}
object EvaluationState extends Enumeration {
val New, Blocked, Ready, Calling, Evaluated = Value
@ -24,8 +24,7 @@ abstract class EvaluateSettings[Scope]
private[this] val transform: Initialize ~> INode = new (Initialize ~> INode) { def apply[T](i: Initialize[T]): INode[T] = i match {
case k: Keyed[s, T] => single(getStatic(k.scopedKey), k.transform)
case a: Apply[hl,T] => new MixedNode(a.inputs transform transform, a.f)
case u: Uniform[s, T] => new UniformNode(u.inputs map transform.fn[s], u.f)
case a: Apply[k,T] => new MixedNode[k,T]( a.alist.transform[Initialize, INode](a.inputs, transform), a.f, a.alist)
case b: Bind[s,T] => new BindNode[s,T]( transform(b.in), x => transform(b.f(x)))
case v: Value[T] => constant(v.value)
case o: Optional[s,T] => o.a match {
@ -155,8 +154,9 @@ abstract class EvaluateSettings[Scope]
protected def dependsOn: Seq[INode[_]]
protected def evaluate0(): Unit
}
private[this] def constant[T](f: () => T): INode[T] = new MixedNode[HNil, T](KNil, _ => f())
private[this] def single[S,T](in: INode[S], f: S => T): INode[T] = new MixedNode[S :+: HNil, T](in :^: KNil, hl => f(hl.head))
private[this] def constant[T](f: () => T): INode[T] = new MixedNode[ConstK[Unit]#l, T]((), _ => f(), AList.empty)
private[this] def single[S,T](in: INode[S], f: S => T): INode[T] = new MixedNode[ ({ type l[L[x]] = L[S] })#l, T](in, f, AList.single[S])
private[this] final class BindNode[S,T](in: INode[S], f: S => INode[T]) extends INode[T]
{
protected def dependsOn = in :: Nil
@ -166,14 +166,9 @@ abstract class EvaluateSettings[Scope]
setValue(value)
}
}
private[this] final class UniformNode[S,T](in: Seq[INode[S]], f: Seq[S] => T) extends INode[T]
private[this] final class MixedNode[K[L[x]], T](in: K[INode], f: K[Id] => T, alist: AList[K]) extends INode[T]
{
protected def dependsOn = in
protected def evaluate0(): Unit = setValue( f(in.map(_.get)) )
}
private[this] final class MixedNode[HL <: HList, T](in: KList[INode, HL], f: HL => T) extends INode[T]
{
protected def dependsOn = in.toList
protected def evaluate0(): Unit = setValue( f( in down getValue ) )
protected def dependsOn = alist.toList(in)
protected def evaluate0(): Unit = setValue( f( alist.transform(in, getValue) ) )
}
}

View File

@ -1,76 +1,49 @@
/* sbt -- Simple Build Tool
* Copyright 2010 Mark Harrah
*/
package sbt
import Types._
import Types._
import Classes.Applicative
/** A higher-order heterogeneous list. It has a type constructor M[_] and
* 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.
*
* 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]
/** Heterogeneous list with each element having type M[T] for some type T.*/
sealed trait KList[+M[_]]
{
type Raw = HL
/** Transform to the underlying HList type.*/
def down(implicit ev: M ~> Id): HL
/** Apply a natural transformation. */
def transform[N[_]](f: M ~> N): KList[N, HL]
/** Convert to a List. */
type Transform[N[_]] <: KList[N]
/** Apply the natural transformation `f` to each element. */
def transform[N[_]](f: M ~> N): Transform[N]
def foldr[T](f: (M[_], T) => T, init: T): T = init // had trouble defining it in KNil
def apply[N[x] >: M[x], Z](f: Transform[Id] => Z)(implicit ap: Applicative[N]): N[Z]
def traverse[N[_], P[_]](f: M ~> (N P)#l)(implicit np: Applicative[N]): N[Transform[P]]
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]]
final case class KCons[H, +T <: KList[M], +M[_]](head: M[H], tail: T) extends KList[M]
{
def kcons[H,T <: HList](h: M[H], acc: P[T]): P[H :+: T]
def knil: P[HNil]
}
final type Transform[N[_]] = KCons[H, tail.Transform[N], N]
final case class KCons[H, T <: HList, +M[_]](head: M[H], tail: KList[M,T]) extends KList[M, H :+: T]
def transform[N[_]](f: M ~> N) = KCons(f(head), tail.transform(f))
def toList: List[M[_]] = head :: tail.toList
def apply[N[x] >: M[x], Z](f: Transform[Id] => Z)(implicit ap: Applicative[N]): N[Z] =
{
val g = (t: tail.Transform[Id]) => (h: H) =>f( KCons[H, tail.Transform[Id], Id](h, t) )
ap.apply( tail.apply[N, H => Z](g), head )
}
def traverse[N[_], P[_]](f: M ~> (N P)#l)(implicit np: Applicative[N]): N[Transform[P]] =
{
val tt: N[tail.Transform[P]] = tail.traverse[N,P](f)
val g = (t: tail.Transform[P]) => (h: P[H]) => KCons(h, t)
np.apply(np.map(g, tt), f(head))
}
def :^:[A,N[x] >: M[x]](h: N[A]) = KCons(h, this)
override def foldr[T](f: (M[_], T) => T, init: T): T = f(head, tail.foldr(f, init))
}
sealed abstract class KNil extends KList[Nothing]
{
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
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)
final type Transform[N[_]] = KNil
final def transform[N[_]](f: Nothing ~> N): Transform[N] = KNil
final def toList = Nil
final def apply[N[x], Z](f: KNil => Z)(implicit ap: Applicative[N]): N[Z] = ap.pure(f(KNil))
final def traverse[N[_], P[_]](f: Nothing ~> (N P)#l)(implicit np: Applicative[N]): N[KNil] = np.pure(KNil)
}
sealed class KNil extends KList[Nothing, 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 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 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))
// 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
case object KNil extends KNil {
def :^:[M[_], H](h: M[H]): KCons[H, KNil, M] = KCons(h, this)
}

View File

@ -61,10 +61,12 @@ trait Init[Scope]
def setting[T](key: ScopedKey[T], init: Initialize[T], pos: SourcePosition = NoPosition): Setting[T] = new Setting[T](key, init, pos)
def value[T](value: => T): Initialize[T] = new Value(value _)
def optional[T,U](i: Initialize[T])(f: Option[T] => U): Initialize[U] = new Optional(Some(i), f)
def update[T](key: ScopedKey[T])(f: T => T): Setting[T] = new Setting[T](key, app(key :^: KNil)(hl => f(hl.head)), NoPosition)
def update[T](key: ScopedKey[T])(f: T => T): Setting[T] = new Setting[T](key, map(key)(f), NoPosition)
def bind[S,T](in: Initialize[S])(f: S => Initialize[T]): Initialize[T] = new Bind(f, in)
def app[HL <: HList, T](inputs: KList[Initialize, HL])(f: HL => T): Initialize[T] = new Apply(f, inputs)
def uniform[S,T](inputs: Seq[Initialize[S]])(f: Seq[S] => T): Initialize[T] = new Uniform(f, inputs)
def map[S,T](in: Initialize[S])(f: S => T): Initialize[T] = new Apply[ ({ type l[L[x]] = L[S] })#l, T](f, in, AList.single[S])
def app[K[L[x]], T](inputs: K[Initialize])(f: K[Id] => T)(implicit alist: AList[K]): Initialize[T] = new Apply[K, T](f, inputs, alist)
def uniform[S,T](inputs: Seq[Initialize[S]])(f: Seq[S] => T): Initialize[T] =
new Apply[({ type l[L[x]] = List[L[S]] })#l, T](f, inputs.toList, AList.seq[S])
def empty(implicit delegates: Scope => Seq[Scope]): Settings[Scope] = new Settings0(Map.empty, delegates)
def asTransform(s: Settings[Scope]): ScopedKey ~> Id = new (ScopedKey ~> Id) {
@ -219,11 +221,12 @@ trait Init[Scope]
def apply[S](g: T => S): Initialize[S]
def mapReferenced(g: MapScoped): Initialize[T]
def validateReferenced(g: ValidateRef): ValidatedInit[T]
def zip[S](o: Initialize[S]): Initialize[(T,S)] = zipWith(o)((x,y) => (x,y))
def zipWith[S,U](o: Initialize[S])(f: (T,S) => U): Initialize[U] =
new Apply[T :+: S :+: HNil, U]( { case t :+: s :+: HNil => f(t,s)}, this :^: o :^: KNil)
def mapConstant(g: MapConstant): Initialize[T]
def evaluate(map: Settings[Scope]): T
def zip[S](o: Initialize[S]): Initialize[(T,S)] = zipTupled(o)(idFun)
def zipWith[S,U](o: Initialize[S])(f: (T,S) => U): Initialize[U] = zipTupled(o)(f.tupled)
private[this] def zipTupled[S,U](o: Initialize[S])(f: ((T,S)) => U): Initialize[U] =
new Apply[({ type l[L[x]] = (L[T], L[S]) })#l, U](f, (this, o), AList.tuple2[T,S])
}
object Initialize
{
@ -330,34 +333,21 @@ trait Init[Scope]
def mapConstant(g: MapConstant) = this
def evaluate(map: Settings[Scope]): T = value()
}
private[sbt] final class Apply[HL <: HList, T](val f: HL => T, val inputs: KList[Initialize, HL]) extends Initialize[T]
private[sbt] final class Apply[K[L[x]], T](val f: K[Id] => T, val inputs: K[Initialize], val alist: AList[K]) extends Initialize[T]
{
def dependencies = deps(inputs.toList)
def dependencies = deps(alist.toList(inputs))
def mapReferenced(g: MapScoped) = mapInputs( mapReferencedT(g) )
def apply[S](g: T => S) = new Apply(g compose f, inputs)
def apply[S](g: T => S) = new Apply(g compose f, inputs, alist)
def mapConstant(g: MapConstant) = mapInputs( mapConstantT(g) )
def mapInputs(g: Initialize ~> Initialize): Initialize[T] = new Apply(f, inputs transform g)
def evaluate(ss: Settings[Scope]) = f(inputs down evaluateT(ss))
def mapInputs(g: Initialize ~> Initialize): Initialize[T] = new Apply(f, alist.transform(inputs, g), alist)
def evaluate(ss: Settings[Scope]) = f(alist.transform(inputs, evaluateT(ss)))
def validateReferenced(g: ValidateRef) =
{
val tx = inputs transform validateReferencedT(g)
val undefs = tx.toList.flatMap(_.left.toSeq.flatten)
val tx = alist.transform(inputs, validateReferencedT(g))
val undefs = alist.toList(tx).flatMap(_.left.toSeq.flatten)
val get = new (ValidatedInit ~> Initialize) { def apply[T](vr: ValidatedInit[T]) = vr.right.get }
if(undefs.isEmpty) Right(new Apply(f, tx transform get)) else Left(undefs)
if(undefs.isEmpty) Right(new Apply(f, alist.transform(tx, get), alist)) else Left(undefs)
}
}
private[sbt] final class Uniform[S, T](val f: Seq[S] => T, val inputs: Seq[Initialize[S]]) extends Initialize[T]
{
def dependencies = deps(inputs)
def mapReferenced(g: MapScoped) = new Uniform(f, inputs map mapReferencedT(g).fn)
def validateReferenced(g: ValidateRef) =
{
val (undefs, ok) = Util.separateE(inputs map validateReferencedT(g).fn )
if(undefs.isEmpty) Right( new Uniform(f, ok) ) else Left(undefs.flatten)
}
def apply[S](g: T => S) = new Uniform(g compose f, inputs)
def mapConstant(g: MapConstant) = new Uniform(f, inputs map mapConstantT(g).fn)
def evaluate(ss: Settings[Scope]) = f(inputs map evaluateT(ss).fn )
}
private def remove[T](s: Seq[T], v: T) = s filterNot (_ == v)
}

View File

@ -7,6 +7,7 @@ trait TypeFunctions
{
type Id[X] = X
sealed trait Const[A] { type Apply[B] = A }
sealed trait ConstK[A] { type l[L[x]] = A }
sealed trait Compose[A[_], B[_]] { type Apply[T] = A[B[T]] }
sealed trait [A[_], B[_]] { type l[T] = A[B[T]] }
sealed trait P1of2[M[_,_], A] { type Apply[B] = M[A,B]; type Flip[B] = M[B, A] }
@ -16,6 +17,7 @@ trait TypeFunctions
final val some = new (Id ~> Some) { def apply[T](t: T) = Some(t) }
final def idFun[T] = (t: T) => t
final def const[A,B](b: B): A=> B = _ => b
final def idK[M[_]]: M ~> M = new (M ~> M) { def apply[T](m: M[T]): M[T] = m }
def nestCon[M[_], N[_], G[_]](f: M ~> N): (M G)#l ~> (N G)#l =
f.asInstanceOf[(M G)#l ~> (N G)#l] // implemented with a cast to avoid extra object+method call. castless version:
@ -26,7 +28,6 @@ trait TypeFunctions
implicit def toFn1[A,B](f: A => B): Fn1[A,B] = new Fn1[A,B] {
def [C](g: C => A) = f compose g
}
def idK[M[_]]: M ~> M = new (M ~> M) { def apply[T](m: M[T]): M[T] = m }
type Endo[T] = T=>T
type ~>|[A[_],B[_]] = A ~> Compose[Option, B]#Apply

View File

@ -4,15 +4,10 @@
package sbt
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
}
trait Types extends TypeFunctions
{
val :^: = KCons
val :+: = HCons
type :+:[H, T <: HList] = HCons[H,T]
val :+: = HCons
}

View File

@ -1,19 +0,0 @@
/* sbt -- Simple Build Tool
* Copyright 2010 Mark Harrah
*/
package sbt
import Types._
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 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") }
val head = new (List ~> Id) { def apply[T](xs: List[T]): T = xs.head }
val z = y down head
val m2 = z match { case 3 :+: "asdf" :+: HNil => println("true") }
}

View File

@ -13,6 +13,7 @@ object PMapTest
mp(Some(3)) = 9
val x = Some(3) :^: Some("asdf") :^: KNil
val y = x.transform[Id](mp)
val z = y.down
z match { case 9 :+: "a" :+: HNil => println("true") }
assert(y.head == 9)
assert(y.tail.head == "a")
assert(y.tail.tail == KNil)
}

View File

@ -49,7 +49,7 @@ object SettingsUsage
// Define some settings
val mySettings: Seq[Setting[_]] = Seq(
setting( a3, value( 3 ) ),
setting( b4, app(a4 :^: KNil) { case av :+: HNil => av * 3 } ),
setting( b4, map(a4)(_ * 3)),
update(a5)(_ + 1)
)