我看不到获取嵌套类型子类型的方法,有可能吗?
type IN[A,B] = {
type X = A
type Y = B
}
trait INH[IN[A,B]] {
type X = IN#X
type Y = IN#Y
}
但这无法编译...
更新
我将扩展这种情况:
有一些类:A,B,C,N-是状态类,我想实现路径依赖的对象:
abstract class State
trait UN[T <: |∨|[_, _]] {
type U[I] = T#λ[I]
}
case class A() extend State
case class B() extend State
case class C(state: State) extend State with UN[(A |∨| B)]
case class D(state: State) extend State with UN[(A |∨| B |∨| C)]
case class Z() extend State
因此,联合类型的Curry Howard定义是:
type ![S] = S => Nothing
type !![S] = ![![S]]
type ∨[T, U] = ![![T] with ![U]]
type |∨|[T, U] = { type λ[X] = !![X] <:< (T ∨ U) }
所以我试图做类似的事情,但是没有成功:
case class C(state: State) {
def test[T <: State](t:T)(implicit ev: (A |∨| B)#λ[T]) = {}
def apply[T <: State](state: T)(implicit ev: (A |∨| B)#λ[T]) = C(state)
}
val a = A(); val b = B(); val z = Z()
val ca = C(a); val cb = C(b)
ca.test(a) // compilation OK
val cz = C(n) // that shouldn't compile but it's
答案 0 :(得分:2)
您必须按照以下方式进行操作:
trait IN[A, B] {
type X = A
type Y = B
}
trait INH[T <: IN[_, _]] {
type X = T#X
type Y = T#Y
}
答案 1 :(得分:0)
talex的答案是正确的,但请注意,Scala 3中将不允许在抽象类型成员上进行这种类型投影(在2020年之前不会出现)。
您的用例似乎有点奇怪,为什么不简单地将IN
声明为
trait IN {
type A
type B
}
然后,您可以直接以A
的身份访问IN#A
,或者最好在Scala 3中允许访问in
的实例IN
,并以in.A
身份访问。
如果您想以简明的方式约束A
,B
或两者,则可以使用类型细化并定义别名:
type INWithSpecificA[+AA] = IN {
type A <: AA
}
B
也一样。我个人发现,这种设计比talex的建议更具灵活性。