From 2608f8ade65f57e2cbc36d0a601e272b141eecb3 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 15 Feb 2020 13:08:40 +0000 Subject: [PATCH] Document parts of AList & components of TupleSyntax Also, extract the AList.SplitK type lambda helper for call-site reuse. --- .../main/scala/sbt/internal/util/appmacro/Instance.scala | 3 +-- .../src/main/scala/sbt/internal/util/AList.scala | 7 +++++-- main-settings/src/main/scala/sbt/Structure.scala | 5 ++++- 3 files changed, 10 insertions(+), 5 deletions(-) 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 489ec3d4f..f077ed5ab 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 @@ -223,8 +223,7 @@ object Instance { def map[S, T](in: M[S], f: S => T): M[T] = a.map(in, (bv: B[S]) => b.map(bv, f)) def app[K[L[x]], Z](in: K[M], f: K[Id] => Z)(implicit alist: AList[K]): A[B[Z]] = { val g: K[B] => B[Z] = in => b.app[K, Z](in, f) - type Split[L[x]] = K[(L ∙ B)#l] - a.app[Split, B[Z]](in, g)(AList.asplit(alist)) + a.app[AList.SplitK[K, B]#l, B[Z]](in, g)(AList.asplit(alist)) } } } 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 1c37ebf36..ca10d2356 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 @@ -91,9 +91,12 @@ object AList { ): N[P[A]] = f(a) } - type ASplit[K[L[x]], B[x]] = AList[λ[L[x] => K[(L ∙ B)#l]]] + /** Example: calling `AList.SplitK[K, Task]#l` returns the type lambda `A[x] => K[A[Task[x]]`. */ + sealed trait SplitK[K[L[x]], B[x]] { type l[A[x]] = K[(A ∙ B)#l] } - /** AList that operates on the outer type constructor `A` of a composition `[x] A[B[x]]` for type constructors `A` and `B`*/ + type ASplit[K[L[x]], B[x]] = AList[SplitK[K, 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] { type Split[L[x]] = K[(L ∙ B)#l] diff --git a/main-settings/src/main/scala/sbt/Structure.scala b/main-settings/src/main/scala/sbt/Structure.scala index f29ca0fa5..388fbf943 100644 --- a/main-settings/src/main/scala/sbt/Structure.scala +++ b/main-settings/src/main/scala/sbt/Structure.scala @@ -462,14 +462,17 @@ object Scoped { ) { type App[T] = Initialize[Task[T]] + + /** A higher-kinded function, where each parameter shares the same type constructor `M[_]`. */ type Fun[M[_], Ret] + /** Convert the higher-kinded function to a Function1. For tuples that means call `.tupled`. */ protected def convert[M[_], Ret](f: Fun[M, Ret]): K[M] => Ret 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[λ[L[x] => K[(L ∙ Task)#l]], Task[T]](inputs)(f)(AList.asplit[K, Task](a)) + Def.app[AList.SplitK[K, 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)))