mirror of https://github.com/sbt/sbt.git
minor updates to utilities
This commit is contained in:
parent
e30368b314
commit
4a0461c34f
|
|
@ -3,12 +3,40 @@
|
|||
*/
|
||||
package sbt
|
||||
|
||||
import Relation._
|
||||
|
||||
object Relation
|
||||
{
|
||||
/** Constructs a new immutable, finite relation that is initially empty. */
|
||||
def empty[A,B]: Relation[A,B] = make(Map.empty, Map.empty)
|
||||
def make[A,B](forward: Map[A,Set[B]], reverse: Map[B, Set[A]]): Relation[A,B] = new MRelation(forward, reverse)
|
||||
def reconstruct[A,B](forward: Map[A, Set[B]]): Relation[A,B] =
|
||||
{
|
||||
val reversePairs = for( (a,bs) <- forward.view; b <- bs.view) yield (b, a)
|
||||
val reverse = (Map.empty[B,Set[A]] /: reversePairs) { case (m, (b, a)) => add(m, b, a :: Nil) }
|
||||
make(forward, reverse)
|
||||
}
|
||||
|
||||
|
||||
private[sbt] def remove[X,Y](map: M[X,Y], from: X, to: Y): M[X,Y] =
|
||||
map.get(from) match {
|
||||
case Some(tos) =>
|
||||
val newSet = tos - to
|
||||
if(newSet.isEmpty) map - from else map.updated(from, newSet)
|
||||
case None => map
|
||||
}
|
||||
|
||||
private[sbt] def combine[X,Y](a: M[X,Y], b: M[X,Y]): M[X,Y] =
|
||||
(a /: b) { (map, mapping) => add(map, mapping._1, mapping._2) }
|
||||
|
||||
private[sbt] def add[X,Y](map: M[X,Y], from: X, to: Iterable[Y]): M[X,Y] =
|
||||
map.updated(from, get(map, from) ++ to)
|
||||
|
||||
private[sbt] def get[X,Y](map: M[X,Y], t: X): Set[Y] = map.getOrElse(t, Set.empty[Y])
|
||||
|
||||
private[sbt] type M[X,Y] = Map[X, Set[Y]]
|
||||
}
|
||||
|
||||
/** Binary relation between A and B. It is a set of pairs (_1, _2) for _1 in A, _2 in B. */
|
||||
trait Relation[A,B]
|
||||
{
|
||||
|
|
@ -49,8 +77,6 @@ trait Relation[A,B]
|
|||
}
|
||||
private final class MRelation[A,B](fwd: Map[A, Set[B]], rev: Map[B, Set[A]]) extends Relation[A,B]
|
||||
{
|
||||
type M[X,Y] = Map[X, Set[Y]]
|
||||
|
||||
def forwardMap = fwd
|
||||
def reverseMap = rev
|
||||
|
||||
|
|
@ -65,9 +91,9 @@ private final class MRelation[A,B](fwd: Map[A, Set[B]], rev: Map[B, Set[A]]) ext
|
|||
def all: Traversable[(A,B)] = fwd.iterator.flatMap { case (a, bs) => bs.iterator.map( b => (a,b) ) }.toTraversable
|
||||
|
||||
def +(pair: (A,B)) = this + (pair._1, Set(pair._2))
|
||||
def +(from: A, to: B) = this + (from, Set(to))
|
||||
def +(from: A, to: B) = this + (from, to :: Nil)
|
||||
def +(from: A, to: Iterable[B]) =
|
||||
new MRelation( add(fwd, from, to), (rev /: to) { (map, t) => add(map, t, Seq(from)) })
|
||||
new MRelation( add(fwd, from, to), (rev /: to) { (map, t) => add(map, t, from :: Nil) })
|
||||
|
||||
def ++(rs: Iterable[(A,B)]) = ((this: Relation[A,B]) /: rs) { _ + _ }
|
||||
def ++(other: Relation[A,B]) = new MRelation[A,B]( combine(fwd, other.forwardMap), combine(rev, other.reverseMap) )
|
||||
|
|
@ -84,21 +110,5 @@ private final class MRelation[A,B](fwd: Map[A, Set[B]], rev: Map[B, Set[A]]) ext
|
|||
case None => this
|
||||
}
|
||||
|
||||
private def remove[X,Y](map: M[X,Y], from: X, to: Y): M[X,Y] =
|
||||
map.get(from) match {
|
||||
case Some(tos) =>
|
||||
val newSet = tos - to
|
||||
if(newSet.isEmpty) map - from else map.updated(from, newSet)
|
||||
case None => map
|
||||
}
|
||||
|
||||
private def combine[X,Y](a: M[X,Y], b: M[X,Y]): M[X,Y] =
|
||||
(a /: b) { (map, mapping) => add(map, mapping._1, mapping._2) }
|
||||
|
||||
private[this] def add[X,Y](map: M[X,Y], from: X, to: Iterable[Y]): M[X,Y] =
|
||||
map.updated(from, get(map, from) ++ to)
|
||||
|
||||
private[this] def get[X,Y](map: M[X,Y], t: X): Set[Y] = map.getOrElse(t, Set.empty[Y])
|
||||
|
||||
override def toString = all.map { case (a,b) => a + " -> " + b }.mkString("Relation [", ", ", "]")
|
||||
}
|
||||
|
|
@ -6,9 +6,9 @@ package sbt
|
|||
trait TypeFunctions
|
||||
{
|
||||
type Id[X] = X
|
||||
trait Const[A] { type Apply[B] = A }
|
||||
trait Compose[A[_], B[_]] { type Apply[T] = A[B[T]] }
|
||||
trait P1of2[M[_,_], A] { type Apply[B] = M[A,B]; type Flip[B] = M[B, A] }
|
||||
sealed trait Const[A] { type Apply[B] = A }
|
||||
sealed trait Compose[A[_], B[_]] { type Apply[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) }
|
||||
|
|
|
|||
Loading…
Reference in New Issue