私が何とかできないことの最小の例を書きました。私は間違った方法ですか?
object minNotWoringkExample {
import shapeless._
def typed[T](t: => T) {}
class Bar {
type L <: HList
}
class Foo {
type UPDATE[L <: HList] <: HList
}
class FooI extends Foo {
type UPDATE[L <: HList] = FilterNot[L, FooI]#Out
}
def update[O <: Foo, B <: Bar] = new Bar {
type L = O#UPDATE[B#L]
}
val myBar = new Bar {
type L = FooI :: Foo :: HNil
}
val myUpdatedBar = update[FooI, Bar {type L = FooI :: Foo :: HNil}]
typed[Bar {type L = Foo :: HNil}](myUpdatedBar)
}
HList 型を保持するオブジェクト Bar があります。以前の HList から新しい HList を構築できる型を持つオブジェクト Foo があります。Foo の子クラスである FooI で、この Hlist が構成されていることを宣言します。形状のない FilterNot を使用して Bar を作成し、それを更新して、型をテストすると、次の結果が得られます。
type mismatch;
found : dsl.minWorkExample.Bar{type L = dsl.minWorkExample.FooI#UPDATE[dsl.minWorkExample.Bar{type L = shapeless.::[dsl.minWorkExample.FooI,shapeless.::[dsl.minWorkExample.Foo,shapeless.HNil]]}#L]}
required: dsl.minWorkExample.Bar{type L = shapeless.::[dsl.minWorkExample.Foo,shapeless.HNil]}
typed[Bar{type L = Foo :: HNil}](myUpdatedBar)
私が持っていた場合、それはコンパイルされることに注意してください
FooJ extends Foo {
type UPDATE[L <: HList] = FooJ :: L
}
(そしてバー オブジェクトはインスタンス化され、それに応じてテストされます)
[追加]
型宣言なしで値のみを使用して別のバージョンを試しました。より構造化されているように見えますが、それ以上は機能していません。また、 shapeless.HList.toString は NoSuchMethodException を返しますが、これはまだ私にとって謎です...
object minWorkExample2 extends App {
import shapeless._
def typed[T](t: => T) {}
trait Bar[L <: HList] {
val l: L
override def toString = "Bar " + l
}
abstract class Foo
case class FooI() extends Foo
case class FooII() extends Foo
abstract class FooParser[L <: HList, F <: Foo](l: L) {
val up: HList
type UPDATE = up.type
}
case class FooParserA[L <: HList, F <: Foo](l: L)(implicit val remove: Remove[F, L]) extends FooParser[L, F](l) {
val up = new HListOps[L](l).removeElem[F]._2
}
case class FooParserB[L <: HList, F <: Foo](l: L)(implicit val filter: FilterNot[L, F]) extends FooParser[L, F](l) {
val up = new HListOps[L](l).filterNot[F]
}
def update[F <: Foo, L <: HList, FP <: FooParser[L, F]](fp: FP) = new Bar[FP#UPDATE] {
val l = fp.up
}
val myBar = new Bar[FooI :: FooII :: HNil] {
val l = FooI() :: FooII() :: HNil
}
val myUpdatedBar = update[FooI, FooI :: FooII :: HNil, FooParserA[FooI :: FooII :: HNil, FooI]](new FooParserA[FooI :: FooII :: HNil, FooI](myBar.l))
println(myUpdatedBar.toString)
//typed[Bar[FooII :: HNil]](myUpdatedBar)
}