diff --git a/build.sbt b/build.sbt index 0f1f7a292..80a62a2ed 100644 --- a/build.sbt +++ b/build.sbt @@ -51,6 +51,7 @@ def commonSettings: Seq[Setting[_]] = resolvers += Resolver.typesafeIvyRepo("releases"), resolvers += Resolver.sonatypeRepo("snapshots"), resolvers += "bintray-sbt-maven-releases" at "https://dl.bintray.com/sbt/maven-releases/", + addCompilerPlugin("org.spire-math" % "kind-projector" % "0.9.4" cross CrossVersion.binary), concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "2"), @@ -143,6 +144,18 @@ val collectionProj = (project in file("internal") / "util-collection") mimaBinaryIssueFilters ++= Seq( // Added private[sbt] method to capture State attributes. exclude[ReversedMissingMethodProblem]("sbt.internal.util.AttributeMap.setCond"), + + // Dropped in favour of kind-projector's inline type lambda syntax + exclude[MissingClassProblem]("sbt.internal.util.TypeFunctions$P1of2"), + + // Dropped in favour of kind-projector's polymorphic lambda literals + exclude[MissingClassProblem]("sbt.internal.util.Param"), + exclude[MissingClassProblem]("sbt.internal.util.Param$"), + + // Dropped in favour of plain scala.Function, and its compose method + exclude[MissingClassProblem]("sbt.internal.util.Fn1"), + exclude[DirectMissingMethodProblem]("sbt.internal.util.TypeFunctions.toFn1"), + exclude[DirectMissingMethodProblem]("sbt.internal.util.Types.toFn1"), ), ) .configure(addSbtUtilPosition) @@ -418,7 +431,18 @@ lazy val sbtProj = (project in file("sbt")) crossScalaVersions := Seq(baseScalaVersion), crossPaths := false, mimaSettings, - mimaBinaryIssueFilters ++= sbtIgnoredProblems, + mimaBinaryIssueFilters ++= Vector( + // Added more items to Import trait. + exclude[ReversedMissingMethodProblem]("sbt.Import.sbt$Import$_setter_$WatchSource_="), + exclude[ReversedMissingMethodProblem]("sbt.Import.WatchSource"), + + // Dropped in favour of kind-projector's polymorphic lambda literals + exclude[DirectMissingMethodProblem]("sbt.Import.Param"), + exclude[DirectMissingMethodProblem]("sbt.package.Param"), + + // Dropped in favour of plain scala.Function, and its compose method + exclude[DirectMissingMethodProblem]("sbt.package.toFn1"), + ) ) .configure(addSbtCompilerBridge) @@ -461,14 +485,6 @@ lazy val vscodePlugin = (project in file("vscode-sbt-scala")) } ) -lazy val sbtIgnoredProblems = { - Seq( - // Added more items to Import trait. - exclude[ReversedMissingMethodProblem]("sbt.Import.sbt$Import$_setter_$WatchSource_="), - exclude[ReversedMissingMethodProblem]("sbt.Import.WatchSource") - ) -} - def scriptedTask: Def.Initialize[InputTask[Unit]] = Def.inputTask { val result = scriptedSource(dir => (s: State) => Scripted.scriptedParser(dir)).parsed // publishLocalBinAll.value // TODO: Restore scripted needing only binary jars. diff --git a/core-macros/src/main/scala/sbt/internal/util/appmacro/Instance.scala b/core-macros/src/main/scala/sbt/internal/util/appmacro/Instance.scala index a14637e05..33e614eab 100644 --- a/core-macros/src/main/scala/sbt/internal/util/appmacro/Instance.scala +++ b/core-macros/src/main/scala/sbt/internal/util/appmacro/Instance.scala @@ -32,6 +32,9 @@ import scala.reflect._ import macros._ object Instance { + type Aux[M0[_]] = Instance { type M[x] = M0[x] } + type Aux2[M0[_], N[_]] = Instance { type M[x] = M0[N[x]] } + final val ApplyName = "app" final val FlattenName = "flatten" final val PureName = "pure" @@ -204,19 +207,18 @@ object Instance { import Types._ - implicit def applicativeInstance[A[_]]( - implicit ap: Applicative[A]): Instance { type M[x] = A[x] } = new Instance { - type M[x] = A[x] - def app[K[L[x]], Z](in: K[A], f: K[Id] => Z)(implicit a: AList[K]) = a.apply[A, Z](in, f) - def map[S, T](in: A[S], f: S => T) = ap.map(f, in) - def pure[S](s: () => S): M[S] = ap.pure(s()) - } + implicit def applicativeInstance[A[_]](implicit ap: Applicative[A]): Instance.Aux[A] = + new Instance { + type M[x] = A[x] + def app[K[L[x]], Z](in: K[A], f: K[Id] => Z)(implicit a: AList[K]) = a.apply[A, Z](in, f) + def map[S, T](in: A[S], f: S => T) = ap.map(f, in) + def pure[S](s: () => S): M[S] = ap.pure(s()) + } - type AI[A[_]] = Instance { type M[x] = A[x] } - def compose[A[_], B[_]](implicit a: AI[A], b: AI[B]): Instance { type M[x] = A[B[x]] } = + def compose[A[_], B[_]](implicit a: Aux[A], b: Aux[B]): Instance.Aux2[A, B] = new Composed[A, B](a, b) // made a public, named, unsealed class because of trouble with macros and inference when the Instance is not an object - class Composed[A[_], B[_]](a: AI[A], b: AI[B]) extends Instance { + class Composed[A[_], B[_]](a: Aux[A], b: Aux[B]) extends Instance { type M[x] = A[B[x]] def pure[S](s: () => S): A[B[S]] = a.pure(() => b.pure(s)) def map[S, T](in: M[S], f: S => T): M[T] = a.map(in, (bv: B[S]) => b.map(bv, f)) diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/AList.scala b/internal/util-collection/src/main/scala/sbt/internal/util/AList.scala index 3ab98f72e..cc5343d2f 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/AList.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/AList.scala @@ -27,7 +27,7 @@ trait AList[K[L[x]]] { } object AList { - type Empty = AList[({ type l[L[x]] = Unit })#l] + type Empty = AList[ConstK[Unit]#l] /** AList for Unit, which represents a sequence that is always empty.*/ val empty: Empty = new Empty { @@ -37,7 +37,7 @@ object AList { 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] + type SeqList[T] = AList[λ[L[x] => List[L[T]]]] /** AList for a homogeneous sequence. */ def seq[T]: SeqList[T] = new SeqList[T] { @@ -59,7 +59,7 @@ object AList { } /** AList for the arbitrary arity data structure KList. */ - def klist[KL[M[_]] <: KList[M] { type Transform[N[_]] = KL[N] }]: AList[KL] = new AList[KL] { + def klist[KL[M[_]] <: KList.Aux[M, KL]]: 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) @@ -67,7 +67,7 @@ object AList { override def toList[M[_]](k: KL[M]) = k.toList } - type Single[A] = AList[({ type l[L[x]] = L[A] })#l] + type Single[A] = AList[λ[L[x] => L[A]]] /** AList for a single value. */ def single[A]: Single[A] = new Single[A] { @@ -76,7 +76,7 @@ object AList { 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] + type ASplit[K[L[x]], B[x]] = AList[λ[L[x] => K[(L ∙ B)#l]]] /** AList that operates on the outer type constructor `A` of a composition `[x] A[B[x]]` for type constructors `A` and `B`*/ def asplit[K[L[x]], B[x]](base: AList[K]): ASplit[K, B] = new ASplit[K, B] { diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala index 0fa72edc2..0dfbea73e 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Attributes.scala @@ -196,11 +196,9 @@ object AttributeMap { def apply(entries: AttributeEntry[_]*): AttributeMap = empty ++ entries /** Presents an `AttributeMap` as a natural transformation. */ - implicit def toNatTrans(map: AttributeMap): AttributeKey ~> Id = new (AttributeKey ~> Id) { - def apply[T](key: AttributeKey[T]): T = map(key) - } - + implicit def toNatTrans(map: AttributeMap): AttributeKey ~> Id = λ[AttributeKey ~> Id](map(_)) } + private class BasicAttributeMap(private val backing: Map[AttributeKey[_], Any]) extends AttributeMap { diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/INode.scala b/internal/util-collection/src/main/scala/sbt/internal/util/INode.scala index 90e004efa..939bd9576 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/INode.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/INode.scala @@ -32,27 +32,25 @@ abstract class EvaluateSettings[Scope] { private[this] def getStatic[T](key: ScopedKey[T]): INode[T] = static get key getOrElse sys.error("Illegal reference to key " + key) - private[this] val transform: Initialize ~> INode = new (Initialize ~> INode) { - def apply[T](i: Initialize[T]): INode[T] = i match { - case k: Keyed[s, T] @unchecked => single(getStatic(k.scopedKey), k.transform) - case a: Apply[k, T] @unchecked => - new MixedNode[k, T]( - a.alist.transform[Initialize, INode](a.inputs, transform), - a.f, - a.alist - ) - case b: Bind[s, T] @unchecked => new BindNode[s, T](transform(b.in), x => transform(b.f(x))) - case v: Value[T] @unchecked => constant(v.value) - case v: ValidationCapture[T] @unchecked => strictConstant(v.key) - case t: TransformCapture => strictConstant(t.f) - case o: Optional[s, T] @unchecked => - o.a match { - case None => constant(() => o.f(None)) - case Some(i) => single[s, T](transform(i), x => o.f(Some(x))) - } - case x if x == StaticScopes => - strictConstant(allScopes.asInstanceOf[T]) // can't convince scalac that StaticScopes => T == Set[Scope] - } + private[this] val transform: Initialize ~> INode = λ[Initialize ~> INode] { + case k: Keyed[s, A1$] @unchecked => single(getStatic(k.scopedKey), k.transform) + case a: Apply[k, A1$] @unchecked => + new MixedNode[k, A1$]( + a.alist.transform[Initialize, INode](a.inputs, transform), + a.f, + a.alist + ) + case b: Bind[s, A1$] @unchecked => new BindNode[s, A1$](transform(b.in), x => transform(b.f(x))) + case v: Value[A1$] @unchecked => constant(v.value) + case v: ValidationCapture[A1$] @unchecked => strictConstant(v.key) + case t: TransformCapture => strictConstant(t.f) + case o: Optional[s, A1$] @unchecked => + o.a match { + case None => constant(() => o.f(None)) + case Some(i) => single[s, A1$](transform(i), x => o.f(Some(x))) + } + case x if x == StaticScopes => + strictConstant(allScopes.asInstanceOf[A1$]) // can't convince scalac that StaticScopes => T == Set[Scope] } private[this] lazy val roots: Seq[INode[_]] = compiledSettings flatMap { cs => @@ -84,7 +82,7 @@ abstract class EvaluateSettings[Scope] { if (key.key.isLocal) ss else ss.set(key.scope, key.key, node.get) } - private[this] val getValue = new (INode ~> Id) { def apply[T](node: INode[T]) = node.get } + private[this] val getValue = λ[INode ~> Id](_.get) private[this] def submitEvaluate(node: INode[_]) = submit(node.evaluate()) @@ -204,7 +202,7 @@ abstract class EvaluateSettings[Scope] { 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]) + new MixedNode[λ[L[x] => L[S]], 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 diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/KList.scala b/internal/util-collection/src/main/scala/sbt/internal/util/KList.scala index 42ad69bb9..a68b61788 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/KList.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/KList.scala @@ -29,6 +29,9 @@ sealed trait KList[+M[_]] { /** Discards the heterogeneous type information and constructs a plain List from this KList's elements. */ def toList: List[M[_]] } +object KList { + type Aux[+M[_], Transform0[N[_]]] = KList[M] { type Transform[N[_]] = Transform0[N] } +} final case class KCons[H, +T <: KList[M], +M[_]](head: M[H], tail: T) extends KList[M] { final type Transform[N[_]] = KCons[H, tail.Transform[N], N] diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/PMap.scala b/internal/util-collection/src/main/scala/sbt/internal/util/PMap.scala index a488fb32f..3d8cf19fd 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/PMap.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/PMap.scala @@ -31,8 +31,7 @@ trait IMap[K[_], V[_]] extends (K ~> V) with RMap[K, V] { def remove[T](k: K[T]): IMap[K, V] def mapValue[T](k: K[T], init: V[T], f: V[T] => V[T]): IMap[K, V] def mapValues[V2[_]](f: V ~> V2): IMap[K, V2] - def mapSeparate[VL[_], VR[_]](f: V ~> ({ type l[T] = Either[VL[T], VR[T]] })#l) - : (IMap[K, VL], IMap[K, VR]) + def mapSeparate[VL[_], VR[_]](f: V ~> λ[T => Either[VL[T], VR[T]]]): (IMap[K, VL], IMap[K, VR]) } trait PMap[K[_], V[_]] extends (K ~> V) with RMap[K, V] { @@ -69,7 +68,7 @@ object IMap { def mapValues[V2[_]](f: V ~> V2) = new IMap0[K, V2](backing.mapValues(x => f(x))) - def mapSeparate[VL[_], VR[_]](f: V ~> ({ type l[T] = Either[VL[T], VR[T]] })#l) = { + def mapSeparate[VL[_], VR[_]](f: V ~> λ[T => Either[VL[T], VR[T]]]) = { val mapped = backing.iterator.map { case (k, v) => f(v) match { diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Param.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Param.scala deleted file mode 100644 index 201663b4e..000000000 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Param.scala +++ /dev/null @@ -1,32 +0,0 @@ -/* - * sbt - * Copyright 2011 - 2017, Lightbend, Inc. - * Copyright 2008 - 2010, Mark Harrah - * Licensed under BSD-3-Clause license (see LICENSE) - */ - -package sbt.internal.util - -// Used to emulate ~> literals -trait Param[A[_], B[_]] { - type T - def in: A[T] - def ret(out: B[T]): Unit - def ret: B[T] -} - -object Param { - implicit def pToT[A[_], B[_]](p: Param[A, B] => Unit): A ~> B = new (A ~> B) { - def apply[s](a: A[s]): B[s] = { - val v: Param[A, B] { type T = s } = new Param[A, B] { - type T = s - def in = a - private var r: B[T] = _ - def ret(b: B[T]): Unit = { r = b } - def ret: B[T] = r - } - p(v) - v.ret - } - } -} diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/Settings.scala b/internal/util-collection/src/main/scala/sbt/internal/util/Settings.scala index d6090dc81..910e1c089 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/Settings.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/Settings.scala @@ -101,14 +101,14 @@ trait Init[Scope] { def bind[S, T](in: Initialize[S])(f: S => Initialize[T]): Initialize[T] = new Bind(f, in) 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]) + new Apply[λ[L[x] => L[S]], 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]) + new Apply[λ[L[x] => List[L[S]]], T](f, inputs.toList, AList.seq[S]) /** * The result of this initialization is the validated `key`. @@ -156,9 +156,7 @@ trait Init[Scope] { def empty(implicit delegates: Scope => Seq[Scope]): Settings[Scope] = new Settings0(Map.empty, delegates) - def asTransform(s: Settings[Scope]): ScopedKey ~> Id = new (ScopedKey ~> Id) { - def apply[T](k: ScopedKey[T]): T = getValue(s, k) - } + def asTransform(s: Settings[Scope]): ScopedKey ~> Id = λ[ScopedKey ~> Id](k => getValue(s, k)) def getValue[T](s: Settings[Scope], k: ScopedKey[T]) = s.get(k.scope, k.key) getOrElse (throw new InvalidReference(k)) @@ -246,13 +244,11 @@ trait Init[Scope] { type ValidatedSettings[T] = Either[Seq[Undefined], SettingSeq[T]] - val f = new (SettingSeq ~> ValidatedSettings) { - def apply[T](ks: Seq[Setting[T]]) = { - val (undefs, valid) = Util.separate(ks.zipWithIndex) { - case (s, i) => s validateKeyReferenced refMap(s, i == 0) - } - if (undefs.isEmpty) Right(valid) else Left(undefs.flatten) + val f = λ[SettingSeq ~> ValidatedSettings] { (ks: Seq[Setting[_]]) => + val (undefs, valid) = Util.separate(ks.zipWithIndex) { + case (s, i) => s validateKeyReferenced refMap(s, i == 0) } + if (undefs.isEmpty) Right(valid) else Left(undefs.flatten) } type Undefs[_] = Seq[Undefined] @@ -560,7 +556,7 @@ trait Init[Scope] { 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]) + new Apply[λ[L[x] => (L[T], L[S])], U](f, (this, o), AList.tuple2[T, S]) /** A fold on the static attributes of this and nested Initializes. */ private[sbt] def processAttributes[S](init: S)(f: (S, AttributeMap) => S): S @@ -577,8 +573,7 @@ trait Init[Scope] { def join[T](inits: Seq[Initialize[T]]): Initialize[Seq[T]] = uniform(inits)(idFun) def joinAny[M[_]](inits: Seq[Initialize[M[T]] forSome { type T }]): Initialize[Seq[M[_]]] = - join(inits.asInstanceOf[Seq[Initialize[M[Any]]]]) - .asInstanceOf[Initialize[Seq[M[T] forSome { type T }]]] + join(inits.asInstanceOf[Seq[Initialize[M[_]]]]) } object SettingsDefinition { @@ -686,23 +681,15 @@ trait Init[Scope] { case Right(x) => x } - private[this] lazy val getValidated = - new (ValidatedInit ~> Initialize) { def apply[T](v: ValidatedInit[T]) = handleUndefined[T](v) } + private[this] lazy val getValidated = λ[ValidatedInit ~> Initialize](handleUndefined(_)) // mainly for reducing generated class count private[this] def validateKeyReferencedT(g: ValidateKeyRef) = - new (Initialize ~> ValidatedInit) { - def apply[T](i: Initialize[T]) = i validateKeyReferenced g - } + λ[Initialize ~> ValidatedInit](_ validateKeyReferenced g) - private[this] def mapReferencedT(g: MapScoped) = - new (Initialize ~> Initialize) { def apply[T](i: Initialize[T]) = i mapReferenced g } - - private[this] def mapConstantT(g: MapConstant) = - new (Initialize ~> Initialize) { def apply[T](i: Initialize[T]) = i mapConstant g } - - private[this] def evaluateT(g: Settings[Scope]) = - new (Initialize ~> Id) { def apply[T](i: Initialize[T]) = i evaluate g } + private[this] def mapReferencedT(g: MapScoped) = λ[Initialize ~> Initialize](_ mapReferenced g) + private[this] def mapConstantT(g: MapConstant) = λ[Initialize ~> Initialize](_ mapConstant g) + private[this] def evaluateT(g: Settings[Scope]) = λ[Initialize ~> Id](_ evaluate g) private[this] def deps(ls: Seq[Initialize[_]]): Seq[ScopedKey[_]] = ls.flatMap(_.dependencies) @@ -854,9 +841,7 @@ trait Init[Scope] { def validateKeyReferenced(g: ValidateKeyRef) = { val tx = alist.transform(inputs, validateKeyReferencedT(g)) val undefs = alist.toList(tx).flatMap(_.left.toSeq.flatten) - val get = new (ValidatedInit ~> Initialize) { - def apply[B](vr: ValidatedInit[B]) = vr.right.get - } + val get = λ[ValidatedInit ~> Initialize](_.right.get) if (undefs.isEmpty) Right(new Apply(f, alist.transform(tx, get), alist)) else Left(undefs) } diff --git a/internal/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala b/internal/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala index c0875046c..49c29ff11 100644 --- a/internal/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala +++ b/internal/util-collection/src/main/scala/sbt/internal/util/TypeFunctions.scala @@ -13,25 +13,18 @@ trait TypeFunctions { 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] } - final val left = new (Id ~> P1of2[Left, Nothing]#Flip) { def apply[T](t: T) = Left(t) } - final val right = new (Id ~> P1of2[Right, Nothing]#Apply) { def apply[T](t: T) = Right(t) } - final val some = new (Id ~> Some) { def apply[T](t: T) = Some(t) } + final val left = λ[Id ~> Left[?, Nothing]](Left(_)) + final val right = λ[Id ~> Right[Nothing, ?]](Right(_)) + final val some = λ[Id ~> Some](Some(_)) 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 } + final def idK[M[_]]: M ~> M = λ[M ~> M](m => 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: - - /* new ( (M ∙ G)#l ~> (N ∙ G)#l ) { - def apply[T](mg: M[G[T]]): N[G[T]] = f(mg) - } */ - - implicit def toFn1[A, B](f: A => B): Fn1[A, B] = new Fn1[A, B] { - def ∙[C](g: C => A) = f compose g - } + f.asInstanceOf[(M ∙ G)#l ~> (N ∙ G)#l] // implemented with a cast to avoid extra object+method call. + // castless version: + // λ[(M ∙ G)#l ~> (N ∙ G)#l](f(_)) type Endo[T] = T => T type ~>|[A[_], B[_]] = A ~> Compose[Option, B]#Apply @@ -42,17 +35,13 @@ object TypeFunctions extends TypeFunctions trait ~>[-A[_], +B[_]] { outer => def apply[T](a: A[T]): B[T] // directly on ~> because of type inference limitations - final def ∙[C[_]](g: C ~> A): C ~> B = new (C ~> B) { def apply[T](c: C[T]) = outer.apply(g(c)) } + final def ∙[C[_]](g: C ~> A): C ~> B = λ[C ~> B](c => outer.apply(g(c))) final def ∙[C, D](g: C => D)(implicit ev: D <:< A[D]): C => B[D] = i => apply(ev(g(i))) final def fn[T] = (t: A[T]) => apply[T](t) } object ~> { import TypeFunctions._ - val Id: Id ~> Id = new (Id ~> Id) { def apply[T](a: T): T = a } + val Id: Id ~> Id = idK[Id] implicit def tcIdEquals: (Id ~> Id) = Id } - -trait Fn1[A, B] { - def ∙[C](g: C => A): C => B -} diff --git a/internal/util-collection/src/test/scala/LiteralTest.scala b/internal/util-collection/src/test/scala/LiteralTest.scala deleted file mode 100644 index b479752f7..000000000 --- a/internal/util-collection/src/test/scala/LiteralTest.scala +++ /dev/null @@ -1,21 +0,0 @@ -/* - * sbt - * Copyright 2011 - 2017, Lightbend, Inc. - * Copyright 2008 - 2010, Mark Harrah - * Licensed under BSD-3-Clause license (see LICENSE) - */ - -package sbt.internal.util - -// compilation test -object LiteralTest { - def x[A[_], B[_]](f: A ~> B) = f - - import Param._ - val f = x { (p: Param[Option, List]) => - p.ret(p.in.toList) - } - - val a: List[Int] = f(Some(3)) - val b: List[String] = f(Some("aa")) -} diff --git a/main-settings/src/main/scala/sbt/Previous.scala b/main-settings/src/main/scala/sbt/Previous.scala index a40db6649..62bfd705f 100644 --- a/main-settings/src/main/scala/sbt/Previous.scala +++ b/main-settings/src/main/scala/sbt/Previous.scala @@ -21,9 +21,7 @@ import scala.util.control.NonFatal */ private[sbt] final class Previous(streams: Streams, referenced: IMap[ScopedTaskKey, Referenced]) { private[this] val map = referenced.mapValues(toValue) - private[this] def toValue = new (Referenced ~> ReferencedValue) { - def apply[T](x: Referenced[T]) = new ReferencedValue(x) - } + private[this] def toValue = λ[Referenced ~> ReferencedValue](new ReferencedValue(_)) private[this] final class ReferencedValue[T](referenced: Referenced[T]) { import referenced.{ stamped, task } diff --git a/main-settings/src/main/scala/sbt/Structure.scala b/main-settings/src/main/scala/sbt/Structure.scala index 54a421cfe..bcedc4171 100644 --- a/main-settings/src/main/scala/sbt/Structure.scala +++ b/main-settings/src/main/scala/sbt/Structure.scala @@ -434,14 +434,10 @@ object Scoped { 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] val inputs: K[App] = a.transform(keys, λ[ScopedTaskable ~> App](_.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.app[λ[L[x] => K[(L ∙ Task)#l]], Task[T]](inputs)(f)(AList.asplit[K, Task](a)) 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))) diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index 0c42d86b3..6ec260e86 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -515,10 +515,7 @@ object Project extends ProjectExtra { def fillTaskAxis(scoped: ScopedKey[_]): ScopedKey[_] = ScopedKey(Scope.fillTaskAxis(scoped.scope, scoped.key), scoped.key) - def mapScope(f: Scope => Scope) = new (ScopedKey ~> ScopedKey) { - def apply[T](key: ScopedKey[T]) = - ScopedKey(f(key.scope), key.key) - } + def mapScope(f: Scope => Scope) = λ[ScopedKey ~> ScopedKey](k => ScopedKey(f(k.scope), k.key)) def transform(g: Scope => Scope, ss: Seq[Def.Setting[_]]): Seq[Def.Setting[_]] = { val f = mapScope(g) diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index b10235eac..c6264f671 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -291,12 +291,12 @@ private[sbt] object Load { // 3. resolvedScoped is replaced with the defining key as a value // Note: this must be idempotent. def finalTransforms(ss: Seq[Setting[_]]): Seq[Setting[_]] = { - def mapSpecial(to: ScopedKey[_]) = new (ScopedKey ~> ScopedKey) { - def apply[T](key: ScopedKey[T]) = + def mapSpecial(to: ScopedKey[_]) = λ[ScopedKey ~> ScopedKey]( + (key: ScopedKey[_]) => if (key.key == streams.key) ScopedKey(Scope.fillTaskAxis(Scope.replaceThis(to.scope)(key.scope), to.key), key.key) else key - } + ) def setDefining[T] = (key: ScopedKey[T], value: T) => value match { @@ -304,13 +304,13 @@ private[sbt] object Load { case ik: InputTask[t] => ik.mapTask(tk => setDefinitionKey(tk, key)).asInstanceOf[T] case _ => value } - def setResolved(defining: ScopedKey[_]) = new (ScopedKey ~> Option) { - def apply[T](key: ScopedKey[T]): Option[T] = + def setResolved(defining: ScopedKey[_]) = λ[ScopedKey ~> Option]( + (key: ScopedKey[_]) => key.key match { - case resolvedScoped.key => Some(defining.asInstanceOf[T]) + case resolvedScoped.key => Some(defining.asInstanceOf[A1$]) case _ => None - } - } + } + ) ss.map(s => s mapConstant setResolved(s.key) mapReferenced mapSpecial(s.key) mapInit setDefining) } diff --git a/sbt/src/main/scala/Import.scala b/sbt/src/main/scala/Import.scala index 2e318663d..3a0adc48a 100644 --- a/sbt/src/main/scala/Import.scala +++ b/sbt/src/main/scala/Import.scala @@ -133,7 +133,6 @@ trait Import { type FeedbackProvidedException = sbt.internal.util.FeedbackProvidedException type FilePosition = sbt.internal.util.FilePosition type FilterLogger = sbt.internal.util.FilterLogger - type Fn1[A, B] = sbt.internal.util.Fn1[A, B] val FullLogger = sbt.internal.util.FullLogger type FullLogger = sbt.internal.util.FullLogger val FullReader = sbt.internal.util.FullReader @@ -167,8 +166,6 @@ trait Import { val NoPosition = sbt.internal.util.NoPosition val PMap = sbt.internal.util.PMap type PMap[K[_], V[_]] = sbt.internal.util.PMap[K, V] - val Param = sbt.internal.util.Param - type Param[A[_], B[_]] = sbt.internal.util.Param[A, B] type RMap[K[_], V[_]] = sbt.internal.util.RMap[K, V] val RangePosition = sbt.internal.util.RangePosition type RangePosition = sbt.internal.util.RangePosition diff --git a/tasks-standard/src/main/scala/sbt/std/System.scala b/tasks-standard/src/main/scala/sbt/std/System.scala index 7e7673a33..060bc0d48 100644 --- a/tasks-standard/src/main/scala/sbt/std/System.scala +++ b/tasks-standard/src/main/scala/sbt/std/System.scala @@ -37,9 +37,7 @@ object Transform { /** Applies `map`, returning the result if defined or returning the input unchanged otherwise.*/ implicit def getOrId(map: Task ~>| Task): Task ~> Task = - new (Task ~> Task) { - def apply[T](in: Task[T]): Task[T] = map(in).getOrElse(in) - } + λ[Task ~> Task](in => map(in).getOrElse(in)) def apply(dummies: DummyTaskMap) = taskToNode(getOrId(dummyMap(dummies))) @@ -48,7 +46,7 @@ object Transform { 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 DependsOn(in, deps) => uniform(existToAny(deps))(const(Left(in)) compose all) case Join(in, f) => uniform(in)(f) } def inline[T](t: Task[T]) = t.work match { @@ -58,7 +56,7 @@ object Transform { } 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]) + toNode[T, λ[L[x] => List[L[D]]]](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] { diff --git a/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala b/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala index 5d7bd1b96..b94ea5e1c 100644 --- a/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala +++ b/tasks-standard/src/main/scala/sbt/std/TaskExtra.scala @@ -118,7 +118,7 @@ trait TaskExtra { } 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]) + multInputTask[λ[L[x] => (L[A], L[B])]](in)(AList.tuple2[A, B]) final implicit def multInputTask[K[L[X]]](tasks: K[Task])(implicit a: AList[K]): MultiInTask[K] = new MultiInTask[K] { @@ -248,7 +248,7 @@ object TaskExtra extends TaskExtra { } 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 + multInputTask[λ[L[x] => (L[S], L[S])]]((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(a)(in) diff --git a/tasks-standard/src/test/scala/Test.scala b/tasks-standard/src/test/scala/Test.scala index 07a6c11b6..0574118ca 100644 --- a/tasks-standard/src/test/scala/Test.scala +++ b/tasks-standard/src/test/scala/Test.scala @@ -11,9 +11,9 @@ import sbt.internal.util.AList 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) + multInputTask[λ[L[x] => (L[A], L[B])]]((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) + multInputTask[λ[L[x] => (L[A], L[B], L[C])]]((a, b, c))(AList.tuple3) val a = task(3) val b = task[Boolean](sys.error("test")) diff --git a/tasks/src/main/scala/sbt/Execute.scala b/tasks/src/main/scala/sbt/Execute.scala index 5a60ce706..267a1383a 100644 --- a/tasks/src/main/scala/sbt/Execute.scala +++ b/tasks/src/main/scala/sbt/Execute.scala @@ -54,15 +54,16 @@ private[sbt] final class Execute[A[_] <: AnyRef]( private[this] val reverse = idMap[A[_], Iterable[A[_]]] private[this] val callers = pMap[A, Compose[IDSet, A]#Apply] private[this] val state = idMap[A[_], State] - private[this] val viewCache = pMap[A, ({ type l[t] = Node[A, t] })#l] + private[this] val viewCache = pMap[A, Node[A, ?]] private[this] val results = pMap[A, Result] - private[this] val getResult: A ~> Result = new (A ~> Result) { - def apply[T](a: A[T]): Result[T] = view.inline(a) match { - case Some(v) => Value(v()) - case None => results(a) + private[this] val getResult: A ~> Result = λ[A ~> Result]( + a => + view.inline(a) match { + case Some(v) => Value(v()) + case None => results(a) } - } + ) private[this] var progressState: progress.S = progress.initial private[this] type State = State.Value diff --git a/tasks/src/main/scala/sbt/Result.scala b/tasks/src/main/scala/sbt/Result.scala index 691a54f00..318027579 100644 --- a/tasks/src/main/scala/sbt/Result.scala +++ b/tasks/src/main/scala/sbt/Result.scala @@ -28,12 +28,9 @@ final case class Value[+T](value: T) extends Result[T] { object Result { type Id[X] = X - val tryValue = new (Result ~> Id) { - def apply[T](r: Result[T]): T = - r match { - case Value(v) => v - case Inc(i) => throw i - } + val tryValue = λ[Result ~> Id] { + case Value(v) => v + case Inc(i) => throw i } def tryValues[S](r: Seq[Result[Unit]], v: Result[S]): S = { r foreach tryValue[Unit]