访问类型参数的类型参数

发布于 2024-10-10 18:27:38 字数 938 浏览 2 评论 0原文

我想在一个特征中访问该特征的类型参数的类型参数。无需将此“二阶”类型参数作为另一个“一阶”参数添加到特征中。下面说明了这个问题:

sealed trait A; sealed trait A1 extends A; sealed trait A2 extends A
trait B[ ASpecific <: A ] { type ASpec = ASpecific }
trait D[ ASpecific <: A ] extends B[ ASpecific ]
trait C[ +BSpecific <: B[ _ <: A ]] {
   def unaryOp : C[ D[ BSpecific#ASpec ]]
}

def test( c: C[ B[ A1 ]]) : C[ D[ A1 ]] = c.unaryOp

测试无法编译,因为显然 c.unaryOp 的结果类型为 C[D[A]] 而不是 C[D[A1]],表明 ASpec 只是 _ < 的快捷方式;:A 并不指具体的类型参数。

双类型参数解决方案很简单:

sealed trait A; sealed trait A1 extends A; sealed trait A2 extends A
trait B[ ASpecific <: A ]
trait D[ ASpecific <: A ] extends B[ ASpecific ]
trait C[ ASpecific <: A, +BSpecific <: B[ ASpecific ]] {
   def unaryOp : C[ ASpecific, D[ ASpecific ]]
}

def test( c: C[ A1, B[ A1 ]]) : C[ A1, D[ A1 ]] = c.unaryOp

但我不明白为什么我需要用第二个明显多余的参数来混乱我的源代码。有没有办法从特征B中检索它?

i would like to access, in a trait, the type-parameter of a type-parameter of that trait. without adding this "second-order" type-parameter as another "first-order" parameter to the trait. the following illustrates this problem:

sealed trait A; sealed trait A1 extends A; sealed trait A2 extends A
trait B[ ASpecific <: A ] { type ASpec = ASpecific }
trait D[ ASpecific <: A ] extends B[ ASpecific ]
trait C[ +BSpecific <: B[ _ <: A ]] {
   def unaryOp : C[ D[ BSpecific#ASpec ]]
}

def test( c: C[ B[ A1 ]]) : C[ D[ A1 ]] = c.unaryOp

the test fails to compile because apparently, the c.unaryOp has a result of type C[D[A]] and not C[D[A1]], indicating that ASpec is merely a shortcut for _ <: A and does not refer to the specific type parameter.

the two-type-parameter solution is simple:

sealed trait A; sealed trait A1 extends A; sealed trait A2 extends A
trait B[ ASpecific <: A ]
trait D[ ASpecific <: A ] extends B[ ASpecific ]
trait C[ ASpecific <: A, +BSpecific <: B[ ASpecific ]] {
   def unaryOp : C[ ASpecific, D[ ASpecific ]]
}

def test( c: C[ A1, B[ A1 ]]) : C[ A1, D[ A1 ]] = c.unaryOp

but i don't understand why i need to clutter my source with this second, obviously redundant, parameter. is there no way to retrieve it from trait B?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤凫 2024-10-17 18:27:38

我可以通过在 C 中添加类型别名来使其编译:

sealed trait A; sealed trait A1 extends A; sealed trait A2 extends A
trait B[ ASpecific <: A ] { type ASpec = ASpecific }
trait D[ ASpecific <: A ] extends B[ ASpecific ]
trait C[ +BSpecific <: B[ _ <: A ]] {
   type BSpec = BSpecific#ASpec
   def unaryOp : C[ D[ BSpec ]]
}
def test[X <: C[ B[ A1 ]]](c:X): C[ D[ X#BSpec ]] = c.unaryOp

另一个增强版本的测试:

def test2[K <: A, X <: C[ B[ K ]]](c:X): C[ D[ X#BSpec ]] = c.unaryOp

希望它没有改变您的意图。

I could make it compile by adding a type alias in C:

sealed trait A; sealed trait A1 extends A; sealed trait A2 extends A
trait B[ ASpecific <: A ] { type ASpec = ASpecific }
trait D[ ASpecific <: A ] extends B[ ASpecific ]
trait C[ +BSpecific <: B[ _ <: A ]] {
   type BSpec = BSpecific#ASpec
   def unaryOp : C[ D[ BSpec ]]
}
def test[X <: C[ B[ A1 ]]](c:X): C[ D[ X#BSpec ]] = c.unaryOp

Another enhanced version of test:

def test2[K <: A, X <: C[ B[ K ]]](c:X): C[ D[ X#BSpec ]] = c.unaryOp

Hope it haven't changed your intention.

回忆躺在深渊里 2024-10-17 18:27:38

@pedrofurla(抱歉,我在未登录的情况下无法直接回复)

虽然您的示例可以编译,但我认为您除了 C[D[A]] 之外什么也没有得到,因为正是 X#BSpec_ <: A 的别名...

val x: C[D[A1]] = test(new C[B[A1]] {})

<console>:34: error: type mismatch;
 found   : C[D[A]]
 required: C[D[A1]]
       val x: C[D[A1]] = test(new C[B[A1]] {})
                             ^

@pedrofurla (sorry can't reply directly as i asked without being logged in)

although your example compiles, i think you are not getting anything from that but C[D[A]] because precisely X#BSpec being an alias for _ <: A...

val x: C[D[A1]] = test(new C[B[A1]] {})

<console>:34: error: type mismatch;
 found   : C[D[A]]
 required: C[D[A1]]
       val x: C[D[A1]] = test(new C[B[A1]] {})
                             ^
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文