proper resolvedScoped implementation

This commit is contained in:
Mark Harrah 2011-07-19 21:29:05 -04:00
parent 2c3fc0abd6
commit a6dd6b07b5
2 changed files with 96 additions and 0 deletions

View File

@ -0,0 +1,75 @@
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) )
}
*/

View File

@ -50,6 +50,7 @@ trait Init[Scope]
type CompiledMap = Map[ScopedKey[_], Compiled]
type MapScoped = ScopedKey ~> ScopedKey
type ScopeLocal = ScopedKey[_] => Seq[Setting[_]]
type MapConstant = ScopedKey ~> Option
def setting[T](key: ScopedKey[T], init: Initialize[T]): Setting[T] = new Setting[T](key, init)
def value[T](value: => T): Initialize[T] = new Value(value _)
@ -161,6 +162,7 @@ trait Init[Scope]
def mapReferenced(g: MapScoped): Initialize[T]
def zip[S](o: Initialize[S]): Initialize[(T,S)] = zipWith(o)((x,y) => (x,y))
def zipWith[S,U](o: Initialize[S])(f: (T,S) => U): Initialize[U] = new Joined[T,S,U](this, o, f)
def mapConstant(g: MapConstant): Initialize[T]
def get(map: Settings[Scope]): T
}
object Initialize
@ -190,6 +192,7 @@ trait Init[Scope]
def mapReferenced(g: MapScoped): Setting[T] = new Setting(key, init mapReferenced g)
def mapKey(g: MapScoped): Setting[T] = new Setting(g(key), init)
def mapInit(f: (ScopedKey[T], T) => T): Setting[T] = new Setting(key, init.map(t => f(key,t)))
def mapConstant(g: MapConstant): Setting[T] = new Setting(key, init mapConstant g)
override def toString = "setting(" + key + ")"
}
@ -199,6 +202,11 @@ trait Init[Scope]
def map[Z](g: T => Z): Initialize[Z] = new Optional[S,Z](a, g compose f)
def get(map: Settings[Scope]): T = f(a map asFunction(map))
def mapReferenced(g: MapScoped) = new Optional(mapKey(g), f)
def mapConstant(g: MapConstant): Initialize[T] =
(a flatMap g.fn) match {
case None => this
case s => new Value(() => f(s))
}
private[this] def mapKey(g: MapScoped) = try { a map g.fn } catch { case _: Uninitialized => None }
}
private[this] final class Joined[S,T,U](a: Initialize[S], b: Initialize[T], f: (S,T) => U) extends Initialize[U]
@ -206,6 +214,7 @@ trait Init[Scope]
def dependsOn = a.dependsOn ++ b.dependsOn
def mapReferenced(g: MapScoped) = new Joined(a mapReferenced g, b mapReferenced g, f)
def map[Z](g: U => Z) = new Joined[S,T,Z](a, b, (s,t) => g(f(s,t)))
def mapConstant(g: MapConstant) = new Joined[S,T,U](a mapConstant g, b mapConstant g, f)
def get(map: Settings[Scope]): U = f(a get map, b get map)
}
private[this] final class Value[T](value: () => T) extends Initialize[T]
@ -213,6 +222,7 @@ trait Init[Scope]
def dependsOn = Nil
def mapReferenced(g: MapScoped) = this
def map[S](g: T => S) = new Value[S](() => g(value()))
def mapConstant(g: MapConstant) = this
def get(map: Settings[Scope]): T = value()
}
private[this] final class Apply[HL <: HList, T](val f: HL => T, val inputs: KList[ScopedKey, HL]) extends Initialize[T]
@ -220,6 +230,7 @@ trait Init[Scope]
def dependsOn = inputs.toList
def mapReferenced(g: MapScoped) = new Apply(f, inputs transform g)
def map[S](g: T => S) = new Apply(g compose f, inputs)
def mapConstant(g: MapConstant) = Reduced.reduceH(inputs, g).combine( (keys, expand) => new Apply(f compose expand, keys) )
def get(map: Settings[Scope]) = f(inputs down asTransform(map) )
}
private[this] final class KApply[HL <: HList, M[_], T](val f: KList[M, HL] => T, val inputs: KList[({type l[t] = ScopedKey[M[t]]})#l, HL]) extends Initialize[T]
@ -228,6 +239,11 @@ trait Init[Scope]
def mapReferenced(g: MapScoped) = new KApply[HL, M, T](f, inputs.transform[({type l[t] = ScopedKey[M[t]]})#l]( nestCon(g) ) )
def map[S](g: T => S) = new KApply[HL, M, S](g compose f, inputs)
def get(map: Settings[Scope]) = f(inputs.transform[M]( nestCon[ScopedKey, Id, M](asTransform(map)) ))
def mapConstant(g: MapConstant) =
{
def mk[HLk <: HList](keys: KList[(ScopedKey M)#l, HLk], expand: KList[M, HLk] => KList[M, HL]) = new KApply[HLk, M, T](f compose expand, keys)
Reduced.reduceK[HL, ScopedKey, M](inputs, nestCon(g)) combine mk
}
private[this] def unnest(l: List[ScopedKey[M[T]] forSome { type T }]): List[ScopedKey[_]] = l.asInstanceOf[List[ScopedKey[_]]]
}
private[this] final class Uniform[S, T](val f: Seq[S] => T, val inputs: Seq[ScopedKey[S]]) extends Initialize[T]
@ -235,6 +251,11 @@ trait Init[Scope]
def dependsOn = inputs
def mapReferenced(g: MapScoped) = new Uniform(f, inputs map g.fn[S])
def map[S](g: T => S) = new Uniform(g compose f, inputs)
def mapConstant(g: MapConstant) =
{
val red = Reduced.reduceSeq(inputs, g)
new Uniform(f compose red.expand, red.keys)
}
def get(map: Settings[Scope]) = f(inputs map asFunction(map))
}
private def remove[T](s: Seq[T], v: T) = s filterNot (_ == v)