mirror of https://github.com/sbt/sbt.git
75 lines
3.0 KiB
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) )
|
|
}
|
|
*/ |