我想构建一个管道依赖项,其中 2nd 级别依赖于 1st 一个, 3rd 依赖于 2nd AND 1st 等等......
我已经定义了这样的结构
<scheme-name>example-distributed</scheme-name>
<service-name>DistributedCache</service-name>
<backing-map-scheme>
<local-scheme>
<scheme-ref>example-binary-backing-map</scheme-ref>
</local-scheme>
</backing-map-scheme>
<autostart>true</autostart>
</distributed-scheme>
<local-scheme>
<scheme-name>example-binary-backing-map</scheme-name>
<eviction-policy>HYBRID</eviction-policy>
<high-units>{back-size-limit 0}</high-units>
<unit-calculator>BINARY</unit-calculator>
<expiry-delay>0</expiry-delay>
<cachestore-scheme></cachestore-scheme>
</local-scheme>
到目前为止一切正常。但我无法使用依赖于前两个结构的第三个结构。我尝试过无形trait Level[A <: Level[A]] {
type DependsOn <: Level[DependsOn]
val previousDependencies: List[DependsOn]
}
trait First extends Level[First] {
type DependsOn = Nothing
}
trait Second extends Level[Second] {
type DependsOn = First
}
class FirstLevel extends First {
val previousDependencies = List.empty
}
class SecondLevel(val previousDependencies: List[FirstLevel]) extends Second
和Product
,但我无法正常使用它。我知道它必须是Coproduct
含义和类型,它意味着使用无形Product
。请帮助:)
答案 0 :(得分:1)
您可以使用Shapeless&#39; heterogenous lists(HLists)以及更多自定义的自定义HLists。我会和前者一起去,因为它会更清晰,更容易理解。下面的代码中的主要想法是你保持你的级别的类型链与&#34;累积&#34;途中所有元素类型的类型。
import shapeless.{HNil, HList}
sealed trait Level[MyElement] {
type Previous <: Level[_]
type MyList <: HList
def elements: MyList
}
trait LNil extends Level[Nothing] {
type MyElement = Nothing
type MyList = HNil
}
trait LCons[MyElement] <: Level[MyElement] {
type MyList = shapeless.::[List[MyElement], Previous#MyList]
}
如您所见,MyList从下面的级别保存所有元素类型的HList。现在我们可以提供不那么抽象的实现,允许轻松构建这样的级别:
object ConcreteLNil extends LNil {
def elements = HNil
}
class ConcreteLCons[MyElement, PreviousList <: Level[_]]
(thisElems: List[MyElement], val previous: PreviousList)
extends LCons[MyElement] {
type Previous = PreviousList
type MyElement = String
def elements = thisElems :: previous.elements
}
您现在可以像这样使用它:
val first = new ConcreteLCons(1 :: 2 :: Nil, ConcreteLNil)
val second = new ConcreteLCons("x" :: "y" :: Nil, first)
val third = new ConcreteLCons(1.0 :: Nil, second)
third.elements
// List(1.0) :: List(x, y) :: List(1, 2) :: HNil