sbt/util/collection/Reduced.scala

75 lines
3.0 KiB
Scala

package sbt
import Types._
final case class ReducedH[K[_], HL <: HList, HLk <: HList](keys: KList[K, HLk], expand: HLk => HL)
{
def prepend[T](key: K[T])(g: K ~> Option) =
g(key) match
{
case None => ReducedH[K, T :+: HL, T :+: HLk]( KCons(key, keys), { case v :+: hli => HCons(v, expand(hli)) })
case Some(v) => ReducedH[K, T :+: HL, HLk](keys, hli => HCons(v, expand(hli)))
}
def combine[T](f: (KList[K, HLk], HLk => HL) => T): T = f(keys, expand)
}
final case class ReducedK[K[_], M[_], HL <: HList, HLk <: HList](keys: KList[(K M)#l, HLk], expand: KList[M, HLk] => KList[M, HL])
{
def prepend[T](key: K[M[T]])(g: (K M)#l ~> (Option M)#l): ReducedK[K, M, T :+: HL, _ <: HList] =
g(key) match
{
case None => ReducedK[K, M, T :+: HL, T :+: HLk]( KCons[T, HLk, (K M)#l](key, keys), { case KCons(v, hli) => KCons(v, expand(hli)) })
case Some(v) => ReducedK[K, M, T :+: HL, HLk](keys, hli => KCons(v, expand(hli)) )
}
def combine[T](f: (KList[(K M)#l, HLk], KList[M, HLk] => KList[M, HL]) => T): T = f(keys, expand)
}
final case class ReducedSeq[K[_], T](keys: Seq[K[T]], expand: Seq[T] => Seq[T])
{
def prepend(key: K[T])(g: K ~> Option) =
g(key) match
{
case None => ReducedSeq[K, T](key +: keys, { case Seq(x, xs @ _*) => x +: expand(xs) })
case Some(v) => ReducedSeq[K, T](keys, xs => v +: expand(xs))
}
}
object Reduced
{
def reduceK[HL <: HList, K[_], M[_]](keys: KList[(K M)#l, HL], g: (K M)#l ~> (Option M)#l): ReducedK[K, M, HL, _ <: HList] =
{
type RedK[HL <: HList] = ReducedK[K, M, HL, _ <: HList]
keys.foldr[RedK,(K M)#l] { new KFold[(K M)#l, RedK] {
def knil = emptyK
def kcons[H,T<:HList](h: K[M[H]], acc: RedK[T]): RedK[H :+: T] =
acc.prepend(h)(g)
}}
}
def reduceH[HL <: HList, K[_]](keys: KList[K, HL], g: K ~> Option): ReducedH[K, HL, _ <: HList] =
{
type RedH[HL <: HList] = ReducedH[K, HL, _ <: HList]
keys.foldr { new KFold[K, RedH] {
def knil = emptyH
def kcons[H,T<:HList](h: K[H], acc: RedH[T]): RedH[H :+: T] =
acc.prepend(h)(g)
}}
}
def reduceSeq[K[_], T](keys: Seq[K[T]], g: K ~> Option): ReducedSeq[K, T] = (ReducedSeq[K, T](Nil, idFun) /: keys) { (red, key) => red.prepend(key)(g) }
def emptyH[K[_]] = ReducedH[K, HNil, HNil](KNil, idFun)
def emptyK[K[_], M[_]] = ReducedK[K, M, HNil, HNil](KNil, idFun)
}
/*
def mapConstant(inputs: Seq[ScopedKey[S]], g: ScopedKey ~> Option) =
split(Nil, inputs.head, inputs.tails, g) match
{
None => new Uniform(f, inputs)
Some((left, x, Nil)) => new Uniform(in => f(in :+ x), left)
Some((Nil, x, right)) => new Uniform(in => f(x +: in), right)
Some((left, x, right)) => new Joined(uniformID(left), mapConstant(right), (l,r) => (l ++ (x +: r)) )
}
def split[S, M[_]](acc: List[M[S]], head: M[S], tail: List[M[S]], f: M ~> Option): Option[(Seq[M[S]], S, Seq[M[S]])] =
(f(head), tail) match
{
case (None, Nil) => None
case (None, x :: xs) => split( head :: acc, x, xs, f)
case (Some(v), ts) => Some( (acc.reverse, v, ts) )
}
*/