diff options
author | Li Haoyi <haoyi.sg@gmail.com> | 2017-11-16 23:20:22 -0800 |
---|---|---|
committer | Li Haoyi <haoyi.sg@gmail.com> | 2017-11-16 23:20:22 -0800 |
commit | 5d03f4390f110d87ca4578259fb86405b7febab8 (patch) | |
tree | 04e455bf95157c2ca12b3cee3bd7c8be2acee2cf /core/src/main | |
parent | eaba6c7ed4b1dc29c3b0d05be58f1bfd122f369d (diff) | |
download | mill-5d03f4390f110d87ca4578259fb86405b7febab8.tar.gz mill-5d03f4390f110d87ca4578259fb86405b7febab8.tar.bz2 mill-5d03f4390f110d87ca4578259fb86405b7febab8.zip |
Flesh out a principled implementation of the cross-build monad
Diffstat (limited to 'core/src/main')
-rw-r--r-- | core/src/main/scala/mill/define/Cross.scala | 70 |
1 files changed, 9 insertions, 61 deletions
diff --git a/core/src/main/scala/mill/define/Cross.scala b/core/src/main/scala/mill/define/Cross.scala index 1f457096..8f8c01e8 100644 --- a/core/src/main/scala/mill/define/Cross.scala +++ b/core/src/main/scala/mill/define/Cross.scala @@ -1,67 +1,15 @@ package mill.define -sealed trait Cross[T]{ - def flatMap[V](f: T => Cross[V]): Cross[V] = new Cross.FlatMapping(this, f) - def map[V](f: T => V): Cross[V] = new Cross.Mapping(this, f) - def withFilter(f: T => Boolean): Cross[T] = new Cross.Filtering(this, f) +case class Cross[T](items: List[(List[Any], T)]){ + def flatMap[V](f: T => Cross[V]): Cross[V] = new Cross( + items.flatMap{ + case (l, v) => f(v).items.map{case (l2, v2) => (l2 ::: l, v2)} + } + ) + def map[V](f: T => V): Cross[V] = new Cross(items.map{case (l, v) => (l, f(v))}) + def withFilter(f: T => Boolean): Cross[T] = new Cross(items.filter(t => f(t._2))) } object Cross{ - class Listing[T](val items: Seq[T]) extends Cross[T] - class Mapping[T, V](val parent: Cross[T], val f: T => V) extends Cross[V] - class FlatMapping[T, V](val parent: Cross[T], val f: T => Cross[V]) extends Cross[V] - class Filtering[T](val parent: Cross[T], val f: T => Boolean) extends Cross[T] - - def apply[T](t: T*) = new Cross.Listing(t) - - def evaluate[T](c: Cross[T]): List[(List[Any], T)] = c match{ - case c: Listing[T] => c.items.map(i => List(i) -> i).toList - case c: Mapping[_, T] => evaluate(c.parent).map{case (l, v) => (l, c.f(v))} - case c: FlatMapping[_, T] => - evaluate(c.parent).flatMap{ - case (l, v) => evaluate(c.f(v)).map{case (l2, v2) => (l2 ::: l, v2)} - } - case c: Filtering[T] => evaluate(c.parent).filter(t => c.f(t._2)) - } - def test() = { - val example1 = evaluate( - for(a <- Cross(1, 2, 3)) - yield a.toString - ) - pprint.log(example1) - - val example2 = evaluate( - for{ - a <- Cross(1, 2, 3) - b <- Cross("A", "B", "C") - } yield b * a - ) - pprint.pprintln(example2) - - val example3 = evaluate( - for{ - a <- Cross(1, 2, 3) - b <- Cross("A", "B", "C") - c <- Cross(true, false) - } yield b * a + c - ) - pprint.log(example3) - - val example4 = evaluate( - for{ - a <- Cross(1, 2, 3) - b <- Cross("A", "B", "C") - if !(a == 2 && b == "B") - } yield b * a - ) - pprint.log(example4) - - val example5 = evaluate( - for{ - (a, b) <- for(a <- Cross(1, 2, 3); b <- Cross("A", "B", "C")) yield (a, b) - c <- Cross(true, false) - } yield b * a + c - ) - pprint.log(example5) - } + def apply[T](t: T*) = new Cross(t.map(i => List(i) -> i).toList) }
\ No newline at end of file |