diff options
author | Duncan Mak <duncanmak@gmail.com> | 2017-12-28 01:27:41 -0500 |
---|---|---|
committer | Li Haoyi <haoyi.sg@gmail.com> | 2017-12-27 22:27:41 -0800 |
commit | b2cca82786a5fdf0818b4e6be5885855a95f637e (patch) | |
tree | bf164ef396d46bddb1b6f7d5e9fd5cd6205f69ad | |
parent | cb3c5f06b17de55a3d64faab79c081642b0c5a59 (diff) | |
download | mill-b2cca82786a5fdf0818b4e6be5885855a95f637e.tar.gz mill-b2cca82786a5fdf0818b4e6be5885855a95f637e.tar.bz2 mill-b2cca82786a5fdf0818b4e6be5885855a95f637e.zip |
Generate zipmap definitions for higher arities (#81)
* Remove method defns for zipMap/zip that will be generated.
The trait Applyer will now extend from ApplyerGenerated which will contain the code-generated definitions.
* Script to generate code for Applicative
* Generate the zip methods in Target
* Generate zip methods in ApplicativeTests
* Make sure the full 22-arities are generated
* Move code generator into build.sc.
Remove generate.sc from directories where code will be generated.
* Generate code as part of the SBT also
* Properly wire up the test sources
* Generate all the code in one place
-rw-r--r-- | build.sbt | 112 | ||||
-rwxr-xr-x | build.sc | 104 | ||||
-rw-r--r-- | core/src/main/scala/mill/define/Applicative.scala | 37 | ||||
-rw-r--r-- | core/src/main/scala/mill/define/Task.scala | 47 | ||||
-rw-r--r-- | core/src/test/scala/mill/define/ApplicativeTests.scala | 37 |
5 files changed, 227 insertions, 110 deletions
@@ -22,6 +22,117 @@ val sharedSettings = Seq( }.taskValue ) +val coreSettings = Seq( + sourceGenerators in Compile += Def.task { + object CodeGenerator { + private def generateLetters(n: Int) = { + val base = 'A'.toInt + (0 until n).map(i => (i + base).toChar) + } + + def generateApplyer(dir: File) = { + def generate(n: Int) = { + val uppercases = generateLetters(n) + val lowercases = uppercases.map(Character.toLowerCase) + val typeArgs = uppercases.mkString(", ") + val zipArgs = lowercases.mkString(", ") + val parameters = lowercases.zip(uppercases).map { case (lower, upper) => s"$lower: TT[$upper]" }.mkString(", ") + + val body = s"mapCtx(zip($zipArgs)) { case (($zipArgs), z) => cb($zipArgs, z) }" + val zipmap = s"def zipMap[$typeArgs, Res]($parameters)(cb: ($typeArgs, Ctx) => Z[Res]) = $body" + val zip = s"def zip[$typeArgs]($parameters): TT[($typeArgs)]" + + if (n < 22) List(zipmap, zip).mkString(System.lineSeparator) else zip + } + val output = List( + "package mill.define", + "import scala.language.higherKinds", + "trait ApplyerGenerated[TT[_], Z[_], Ctx] {", + "def mapCtx[A, B](a: TT[A])(f: (A, Ctx) => Z[B]): TT[B]", + (2 to 22).map(generate).mkString(System.lineSeparator), + "}").mkString(System.lineSeparator) + + val file = dir / "ApplicativeGenerated.scala" + IO.write(file, output) + file + } + + def generateTarget(dir: File) = { + def generate(n: Int) = { + val uppercases = generateLetters(n) + val lowercases = uppercases.map(Character.toLowerCase) + val typeArgs = uppercases.mkString(", ") + val args = lowercases.mkString(", ") + val parameters = lowercases.zip(uppercases).map { case (lower, upper) => s"$lower: TT[$upper]" }.mkString(", ") + val body = uppercases.zipWithIndex.map { case (t, i) => s"args[$t]($i)" }.mkString(", ") + + s"def zip[$typeArgs]($parameters) = makeT[($typeArgs)](Seq($args), (args: Ctx) => ($body))" + } + + val output = List( + "package mill.define", + "import scala.language.higherKinds", + "import mill.eval.Result", + "import mill.util.Ctx", + "trait TargetGenerated {", + "type TT[+X]", + "def makeT[X](inputs: Seq[TT[_]], evaluate: Ctx => Result[X]): TT[X]", + (3 to 22).map(generate).mkString(System.lineSeparator), + "}").mkString(System.lineSeparator) + + val file = dir / "TaskGenerated.scala" + IO.write(file, output) + file + } + + def generateSources(dir: File) = { + Seq(generateApplyer(dir), generateTarget(dir)) + } + } + val dir = (sourceManaged in Compile).value + CodeGenerator.generateSources(dir) + }.taskValue, + + sourceGenerators in Test += Def.task { + object CodeGenerator { + private def generateLetters(n: Int) = { + val base = 'A'.toInt + (0 until n).map(i => (i + base).toChar) + } + + def generateApplicativeTest(dir: File) = { + def generate(n: Int): String = { + val uppercases = generateLetters(n) + val lowercases = uppercases.map(Character.toLowerCase) + val typeArgs = uppercases.mkString(", ") + val parameters = lowercases.zip(uppercases).map { case (lower, upper) => s"$lower: Option[$upper]" }.mkString(", ") + val result = lowercases.mkString(", ") + val forArgs = lowercases.map(i => s"$i <- $i").mkString("; ") + s"def zip[$typeArgs]($parameters) = { for ($forArgs) yield ($result) }" + } + + val output = List( + "package mill.define", + "trait OptGenerated {", + (2 to 22).map(generate).mkString(System.lineSeparator), + "}" + ).mkString(System.lineSeparator) + + val file = dir / "ApplicativeTestsGenerated.scala" + IO.write(file, output) + file + } + + def generateTests(dir: File) = { + Seq(generateApplicativeTest(dir)) + } + } + + val dir = (sourceManaged in Test).value + CodeGenerator.generateTests(dir) + }.taskValue +) + val pluginSettings = Seq( scalacOptions in Test ++= { val jarFile = (packageBin in (plugin, Compile)).value @@ -86,6 +197,7 @@ lazy val core = project .dependsOn(plugin) .settings( sharedSettings, + coreSettings, pluginSettings, name := "mill-core", libraryDependencies ++= Seq( @@ -48,7 +48,6 @@ trait MillModule extends SbtScalaModule{ outer => def ivyDeps = Seq(Dep("com.lihaoyi", "utest", "0.6.0")) def testFramework = "mill.UTestFramework" def scalacPluginClasspath = super.scalacPluginClasspath() ++ Seq(CompilerPlugin.jar()) - } } @@ -70,6 +69,109 @@ object Core extends MillModule { def basePath = pwd / 'core + object CodeGenerator { + private def generateLetters(n: Int) = { + val base = 'A'.toInt + (0 until n).map(i => (i + base).toChar) + } + + private def write(dir: String, filename: String, s: String) = { + import java.io.{BufferedWriter, FileWriter} + + val path = java.nio.file.Paths.get(dir, filename) + val w = new BufferedWriter(new FileWriter(path.toFile)) + w.write(s) + w.close() + } + + def generateApplyer(dir: String) = { + def generate(n: Int) = { + val uppercases = generateLetters(n) + val lowercases = uppercases.map(Character.toLowerCase) + val typeArgs = uppercases.mkString(", ") + val zipArgs = lowercases.mkString(", ") + val parameters = lowercases.zip(uppercases).map { case (lower, upper) => s"$lower: TT[$upper]" }.mkString(", ") + + val body = s"mapCtx(zip($zipArgs)) { case (($zipArgs), z) => cb($zipArgs, z) }" + val zipmap = s"def zipMap[$typeArgs, Res]($parameters)(cb: ($typeArgs, Ctx) => Z[Res]) = $body" + val zip = s"def zip[$typeArgs]($parameters): TT[($typeArgs)]" + + if (n < 22) List(zipmap, zip).mkString(System.lineSeparator) else zip + } + val output = List( + "package mill.define", + "import scala.language.higherKinds", + "trait ApplyerGenerated[TT[_], Z[_], Ctx] {", + "def mapCtx[A, B](a: TT[A])(f: (A, Ctx) => Z[B]): TT[B]", + (2 to 22).map(generate).mkString(System.lineSeparator), + "}").mkString(System.lineSeparator) + + write(dir, "ApplicativeGenerated.scala", output) + } + + def generateTarget(dir: String) = { + def generate(n: Int) = { + val uppercases = generateLetters(n) + val lowercases = uppercases.map(Character.toLowerCase) + val typeArgs = uppercases.mkString(", ") + val args = lowercases.mkString(", ") + val parameters = lowercases.zip(uppercases).map { case (lower, upper) => s"$lower: TT[$upper]" }.mkString(", ") + val body = uppercases.zipWithIndex.map { case (t, i) => s"args[$t]($i)" }.mkString(", ") + + s"def zip[$typeArgs]($parameters) = makeT[($typeArgs)](Seq($args), (args: Ctx) => ($body))" + } + + val output = List( + "package mill.define", + "import scala.language.higherKinds", + "import mill.eval.Result", + "import mill.util.Ctx", + "trait TargetGenerated {", + "type TT[+X]", + "def makeT[X](inputs: Seq[TT[_]], evaluate: Ctx => Result[X]): TT[X]", + (3 to 22).map(generate).mkString(System.lineSeparator), + "}").mkString(System.lineSeparator) + write(dir, "TaskGenerated.scala", output) + } + + def generateApplicativeTest(dir: String) = { + def generate(n: Int): String = { + val uppercases = generateLetters(n) + val lowercases = uppercases.map(Character.toLowerCase) + val typeArgs = uppercases.mkString(", ") + val parameters = lowercases.zip(uppercases).map { case (lower, upper) => s"$lower: Option[$upper]" }.mkString(", ") + val result = lowercases.mkString(", ") + val forArgs = lowercases.map(i => s"$i <- $i").mkString("; ") + s"def zip[$typeArgs]($parameters) = { for ($forArgs) yield ($result) }" + } + + val output = List( + "package mill.define", + "trait OptGenerated {", + (2 to 22).map(generate).mkString(System.lineSeparator), + "}" + ).mkString(System.lineSeparator) + + write(dir, "ApplicativeTestsGenerated.scala", output) + } + + def generateSources(p: Path) = { + val dir = p.toString() + generateApplyer(dir) + generateTarget(dir) + } + + def generateTests(p: Path) = { + generateApplicativeTest(p.toString()) + } + } + + def sources = { + CodeGenerator.generateSources(this.basePath / 'src / 'main / 'scala / 'mill / 'define) + CodeGenerator.generateTests(pwd / 'core / 'src / 'test / 'scala / 'mill / 'define) + super.sources + } + val cross = for(jarLabel <- mill.define.Cross("jarA", "jarB", "jarC")) yield new mill.Module{ diff --git a/core/src/main/scala/mill/define/Applicative.scala b/core/src/main/scala/mill/define/Applicative.scala index ddbcccdc..69c506f7 100644 --- a/core/src/main/scala/mill/define/Applicative.scala +++ b/core/src/main/scala/mill/define/Applicative.scala @@ -1,7 +1,7 @@ package mill.define - import scala.annotation.{StaticAnnotation, compileTimeOnly} +import scala.language.higherKinds import scala.reflect.macros.blackbox.Context /** @@ -28,47 +28,14 @@ object Applicative { class ImplicitStub extends StaticAnnotation type Id[+T] = T - trait Applyer[W[_], T[_], Z[_], Ctx]{ + trait Applyer[W[_], T[_], Z[_], Ctx] extends ApplyerGenerated[T, Z, Ctx] { def ctx()(implicit c: Ctx) = c def underlying[A](v: W[A]): T[_] - def mapCtx[A, B](a: T[A])(f: (A, Ctx) => Z[B]): T[B] def zipMap[R]()(cb: Ctx => Z[R]) = mapCtx(zip()){ (_, ctx) => cb(ctx)} def zipMap[A, R](a: T[A])(f: (A, Ctx) => Z[R]) = mapCtx(a)(f) - def zipMap[A, B, R](a: T[A], b: T[B])(cb: (A, B, Ctx) => Z[R]) = mapCtx(zip(a, b)){case ((a, b), x) => cb(a, b, x)} - def zipMap[A, B, C, R](a: T[A], b: T[B], c: T[C]) - (cb: (A, B, C, Ctx) => Z[R]) = mapCtx(zip(a, b, c)){case ((a, b, c), x) => cb(a, b, c, x)} - def zipMap[A, B, C, D, R](a: T[A], b: T[B], c: T[C], d: T[D]) - (cb: (A, B, C, D, Ctx) => Z[R]) = mapCtx(zip(a, b, c, d)){case ((a, b, c, d), x) => cb(a, b, c, d, x)} - def zipMap[A, B, C, D, E, R](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E]) - (cb: (A, B, C, D, E, Ctx) => Z[R]) = mapCtx(zip(a, b, c, d, e)){case ((a, b, c, d, e), x) => cb(a, b, c, d, e, x)} - def zipMap[A, B, C, D, E, F, R](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F]) - (cb: (A, B, C, D, E, F, Ctx) => Z[R]) = mapCtx(zip(a, b, c, d, e, f)){case ((a, b, c, d, e, f), x) => cb(a, b, c, d, e, f, x)} - def zipMap[A, B, C, D, E, F, G, R](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F], g: T[G]) - (cb: (A, B, C, D, E, F, G, Ctx) => Z[R]) = mapCtx(zip(a, b, c, d, e, f, g)){case ((a, b, c, d, e, f, g), x) => cb(a, b, c, d, e, f, g, x)} - def zipMap[A, B, C, D, E, F, G, H, R](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F], g: T[G], h: T[H]) - (cb: (A, B, C, D, E, F, G, H, Ctx) => Z[R]) = mapCtx(zip(a, b, c, d, e, f, g, h)){case ((a, b, c, d, e, f, g, h), x) => cb(a, b, c, d, e, f, g, h, x)} - def zipMap[A, B, C, D, E, F, G, H, I, R](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F], g: T[G], h: T[H], i: T[I]) - (cb: (A, B, C, D, E, F, G, H, I, Ctx) => Z[R]) = mapCtx(zip(a, b, c, d, e, f, g, h, i)){case ((a, b, c, d, e, f, g, h, i), x) => cb(a, b, c, d, e, f, g, h, i, x)} - def zipMap[A, B, C, D, E, F, G, H, I, J, R](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F], g: T[G], h: T[H], i: T[I], j: T[J]) - (cb: (A, B, C, D, E, F, G, H, I, J, Ctx) => Z[R]) = mapCtx(zip(a, b, c, d, e, f, g, h, i, j)){case ((a, b, c, d, e, f, g, h, i, j), x) => cb(a, b, c, d, e, f, g, h, i, j, x)} - - def zipMap[A, B, C, D, E, F, G, H, I, J, K, R](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F], g: T[G], h: T[H], i: T[I], j: T[J], k: T[K]) - (cb: (A, B, C, D, E, F, G, H, I, J, K, Ctx) => Z[R]) = mapCtx(zip(a, b, c, d, e, f, g, h, i, j, k)){case ((a, b, c, d, e, f, g, h, i, j, k), x) => cb(a, b, c, d, e, f, g, h, i, j, k, x)} - def zip(): T[Unit] def zip[A](a: T[A]): T[Tuple1[A]] - def zip[A, B](a: T[A], b: T[B]): T[(A, B)] - def zip[A, B, C](a: T[A], b: T[B], c: T[C]): T[(A, B, C)] - def zip[A, B, C, D](a: T[A], b: T[B], c: T[C], d: T[D]): T[(A, B, C, D)] - def zip[A, B, C, D, E](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E]): T[(A, B, C, D, E)] - def zip[A, B, C, D, E, F](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F]): T[(A, B, C, D, E, F)] - def zip[A, B, C, D, E, F, G](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F], g: T[G]): T[(A, B, C, D, E, F, G)] - def zip[A, B, C, D, E, F, G, H](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F], g: T[G], h: T[H]): T[(A, B, C, D, E, F, G, H)] - def zip[A, B, C, D, E, F, G, H, I](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F], g: T[G], h: T[H], i: T[I]): T[(A, B, C, D, E, F, G, H, I)] - def zip[A, B, C, D, E, F, G, H, I, J](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F], g: T[G], h: T[H], i: T[I], j: T[J]): T[(A, B, C, D, E, F, G, H, I, J)] - def zip[A, B, C, D, E, F, G, H, I, J, K](a: T[A], b: T[B], c: T[C], d: T[D], e: T[E], f: T[F], g: T[G], h: T[H], i: T[I], j: T[J], k: T[K]): T[(A, B, C, D, E, F, G, H, I, J, K)] - } def impl[M[_], T: c.WeakTypeTag, Ctx: c.WeakTypeTag](c: Context) diff --git a/core/src/main/scala/mill/define/Task.scala b/core/src/main/scala/mill/define/Task.scala index 71a98fa7..4dc5f692 100644 --- a/core/src/main/scala/mill/define/Task.scala +++ b/core/src/main/scala/mill/define/Task.scala @@ -36,7 +36,7 @@ trait Target[+T] extends Task[T]{ override def asTarget = Some(this) } -object Target extends Applicative.Applyer[Task, Task, Result, Ctx]{ +object Target extends TargetGenerated with Applicative.Applyer[Task, Task, Result, Ctx] { implicit def apply[T](t: T): Target[T] = macro targetImpl[T] @@ -97,47 +97,17 @@ object Target extends Applicative.Applyer[Task, Task, Result, Ctx]{ ) } + type TT[+X] = Task[X] + def makeT[X](inputs0: Seq[TT[_]], evaluate0: Ctx => Result[X]) = new Task[X] { + val inputs = inputs0 + def evaluate(x: Ctx) = evaluate0(x) + } + def underlying[A](v: Task[A]) = v def mapCtx[A, B](t: Task[A])(f: (A, Ctx) => Result[B]) = t.mapDest(f) def zip() = new Task.Task0(()) def zip[A](a: Task[A]) = a.map(Tuple1(_)) def zip[A, B](a: Task[A], b: Task[B]) = a.zip(b) - def zip[A, B, C](a: Task[A], b: Task[B], c: Task[C]) = new Task[(A, B, C)]{ - val inputs = Seq(a, b, c) - def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2)) - } - def zip[A, B, C, D](a: Task[A], b: Task[B], c: Task[C], d: Task[D]) = new Task[(A, B, C, D)]{ - val inputs = Seq(a, b, c, d) - def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3)) - } - def zip[A, B, C, D, E](a: Task[A], b: Task[B], c: Task[C], d: Task[D], e: Task[E]) = new Task[(A, B, C, D, E)]{ - val inputs = Seq(a, b, c, d, e) - def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4)) - } - def zip[A, B, C, D, E, F](a: Task[A], b: Task[B], c: Task[C], d: Task[D], e: Task[E], f: Task[F]) = new Task[(A, B, C, D, E, F)]{ - val inputs = Seq(a, b, c, d, e, f) - def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4), args[F](5)) - } - def zip[A, B, C, D, E, F, G](a: Task[A], b: Task[B], c: Task[C], d: Task[D], e: Task[E], f: Task[F], g: Task[G]) = new Task[(A, B, C, D, E, F, G)]{ - val inputs = Seq(a, b, c, d, e, f, g) - def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4), args[F](5), args[G](6)) - } - def zip[A, B, C, D, E, F, G, H](a: Task[A], b: Task[B], c: Task[C], d: Task[D], e: Task[E], f: Task[F], g: Task[G], h: Task[H]) = new Task[(A, B, C, D, E, F, G, H)]{ - val inputs = Seq(a, b, c, d, e, f, g, h) - def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4), args[F](5), args[G](6), args[H](7)) - } - def zip[A, B, C, D, E, F, G, H, I](a: Task[A], b: Task[B], c: Task[C], d: Task[D], e: Task[E], f: Task[F], g: Task[G], h: Task[H], i: Task[I]) = new Task[(A, B, C, D, E, F, G, H, I)]{ - val inputs = Seq(a, b, c, d, e, f, g, h, i) - def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4), args[F](5), args[G](6), args[H](7), args[I](8)) - } - def zip[A, B, C, D, E, F, G, H, I, J](a: Task[A], b: Task[B], c: Task[C], d: Task[D], e: Task[E], f: Task[F], g: Task[G], h: Task[H], i: Task[I], j: Task[J]) = new Task[(A, B, C, D, E, F, G, H, I, J)]{ - val inputs = Seq(a, b, c, d, e, f, g, h, i, j) - def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4), args[F](5), args[G](6), args[H](7), args[I](8), args[J](9)) - } - def zip[A, B, C, D, E, F, G, H, I, J, K](a: Task[A], b: Task[B], c: Task[C], d: Task[D], e: Task[E], f: Task[F], g: Task[G], h: Task[H], i: Task[I], j: Task[J], k: Task[K]) = new Task[(A, B, C, D, E, F, G, H, I, J, K)]{ - val inputs = Seq(a, b, c, d, e, f, g, h, i, j, k) - def evaluate(args: Ctx) = (args[A](0), args[B](1), args[C](2), args[D](3), args[E](4), args[F](5), args[G](6), args[H](7), args[I](8), args[J](9), args[K](10)) - } } class TargetImpl[+T](t: Task[T], enclosing: String) extends Target[T] { val inputs = Seq(t) @@ -181,9 +151,6 @@ object Task { def evaluate(args: Ctx) = t0 } - - - abstract class Ops[+T]{ this: Task[T] => def map[V](f: T => V) = new Task.Mapped(this, f) def mapDest[V](f: (T, Ctx) => Result[V]) = new Task.MappedDest(this, f) diff --git a/core/src/test/scala/mill/define/ApplicativeTests.scala b/core/src/test/scala/mill/define/ApplicativeTests.scala index c34ed62a..72b715bb 100644 --- a/core/src/test/scala/mill/define/ApplicativeTests.scala +++ b/core/src/test/scala/mill/define/ApplicativeTests.scala @@ -10,46 +10,15 @@ import scala.language.experimental.macros object ApplicativeTests extends TestSuite { implicit def optionToOpt[T](o: Option[T]): Opt[T] = new Opt(o) class Opt[T](val self: Option[T]) extends Applicative.Applyable[Option, T] - object Opt extends Applicative.Applyer[Opt, Option, Applicative.Id, String]{ + object Opt extends OptGenerated with Applicative.Applyer[Opt, Option, Applicative.Id, String]{ val injectedCtx = "helloooo" def underlying[A](v: Opt[A]) = v.self def apply[T](t: T): Option[T] = macro Applicative.impl[Option, T, String] - type O[+T] = Option[T] - def mapCtx[A, B](a: O[A])(f: (A, String) => B): Option[B] = a.map(f(_, injectedCtx)) + def mapCtx[A, B](a: Option[A])(f: (A, String) => B): Option[B] = a.map(f(_, injectedCtx)) def zip() = Some(()) - def zip[A](a: O[A]) = a.map(Tuple1(_)) - def zip[A, B](a: O[A], b: O[B]) = { - for(a <- a; b <- b) yield (a, b) - } - def zip[A, B, C](a: O[A], b: O[B], c: O[C]) = { - for(a <- a; b <- b; c <- c) yield (a, b, c) - } - def zip[A, B, C, D](a: O[A], b: O[B], c: O[C], d: O[D]) = { - for(a <- a; b <- b; c <- c; d <- d) yield (a, b, c, d) - } - def zip[A, B, C, D, E](a: O[A], b: O[B], c: O[C], d: O[D], e: O[E]) = { - for(a <- a; b <- b; c <- c; d <- d; e <- e) yield (a, b, c, d, e) - } - def zip[A, B, C, D, E, F](a: O[A], b: O[B], c: O[C], d: O[D], e: O[E], f: O[F]) ={ - for(a <- a; b <- b; c <- c; d <- d; e <- e; f <- f) yield (a, b, c, d, e, f) - } - def zip[A, B, C, D, E, F, G](a: O[A], b: O[B], c: O[C], d: O[D], e: O[E], f: O[F], g: O[G]) = { - for(a <- a; b <- b; c <- c; d <- d; e <- e; f <- f; g <- g) yield (a, b, c, d, e, f, g) - } - def zip[A, B, C, D, E, F, G, H](a: O[A], b: O[B], c: O[C], d: O[D], e: O[E], f: O[F], g: O[G], h: O[H]) = { - for(a <- a; b <- b; c <- c; d <- d; e <- e; f <- f; g <- g; h <- h) yield (a, b, c, d, e, f, g, h) - } - def zip[A, B, C, D, E, F, G, H, I](a: O[A], b: O[B], c: O[C], d: O[D], e: O[E], f: O[F], g: O[G], h: O[H], i: O[I]) = { - for(a <- a; b <- b; c <- c; d <- d; e <- e; f <- f; g <- g; h <- h; i <- i) yield (a, b, c, d, e, f, g, h, i) - } - def zip[A, B, C, D, E, F, G, H, I, J](a: O[A], b: O[B], c: O[C], d: O[D], e: O[E], f: O[F], g: O[G], h: O[H], i: O[I], j: O[J]) = { - for(a <- a; b <- b; c <- c; d <- d; e <- e; f <- f; g <- g; h <- h; i <- i; j <- j) yield (a, b, c, d, e, f, g, h, i, j) - } - def zip[A, B, C, D, E, F, G, H, I, J, K](a: O[A], b: O[B], c: O[C], d: O[D], e: O[E], f: O[F], g: O[G], h: O[H], i: O[I], j: O[J], k: O[K]) = { - for(a <- a; b <- b; c <- c; d <- d; e <- e; f <- f; g <- g; h <- h; i <- i; j <- j; k <- k) yield (a, b, c, d, e, f, g, h, i, j, k) - } + def zip[A](a: Option[A]) = a.map(Tuple1(_)) } class Counter{ var value = 0 |