mirror of https://github.com/sbt/sbt.git
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:
parent
eecaeafbdf
commit
8d6dd10798
|
|
@ -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) )
|
||||
|
|
|
|||
|
|
@ -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: _*) }
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]) =
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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) )) }
|
||||
|
|
|
|||
|
|
@ -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]])
|
||||
|
|
|
|||
|
|
@ -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) })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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[_]]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
package sbt
|
||||
|
||||
import Project.Initialize
|
||||
import Def.Initialize
|
||||
import Keys._
|
||||
import classpath.ClasspathUtilities
|
||||
import java.lang.reflect.Method
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
}
|
||||
|
|
@ -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))
|
||||
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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]]]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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) }
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
@ -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 =
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
@ -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) ) )
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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") }
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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)
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue