summaryrefslogtreecommitdiff
path: root/core/src/main
diff options
context:
space:
mode:
authorLi Haoyi <haoyi.sg@gmail.com>2017-11-16 23:20:22 -0800
committerLi Haoyi <haoyi.sg@gmail.com>2017-11-16 23:20:22 -0800
commit5d03f4390f110d87ca4578259fb86405b7febab8 (patch)
tree04e455bf95157c2ca12b3cee3bd7c8be2acee2cf /core/src/main
parenteaba6c7ed4b1dc29c3b0d05be58f1bfd122f369d (diff)
downloadmill-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.scala70
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