Scala 专门化函数内的关联类型
我有一个特性定义了一个关联的类型。在函数中,我希望返回此关联类型,该类型因提供的值而异:Scala 专门化函数内的关联类型,scala,Scala,我有一个特性定义了一个关联的类型。在函数中,我希望返回此关联类型,该类型因提供的值而异: sealed trait Abstract { type T } class Impl1 extends Abstract { type T = Int } class Impl2 extends Abstract { type T = Boolean } object G { def get[A <: Abstract] (x: A): A#T = { x match
sealed trait Abstract {
type T
}
class Impl1 extends Abstract {
type T = Int
}
class Impl2 extends Abstract {
type T = Boolean
}
object G {
def get[A <: Abstract] (x: A): A#T = {
x match {
case i1: Impl1 =>
5
case i2: Impl2 =>
true
}
}
}
我如何解决这个问题?您的
匹配
条件给出了任何VAL结果,它对A#T
一无所知。您应该使用.asInstanceOf[A#T]
进行结果或外部模式匹配
val z = x match {
case i1: Impl1 =>
5
case i2: Impl2 =>
true
}
z match {
case x: A#T => x
}
您的
match
条件给出了AnyVal结果,它对A#T
一无所知。您应该使用.asInstanceOf[A#T]
进行结果或外部模式匹配
val z = x match {
case i1: Impl1 =>
5
case i2: Impl2 =>
true
}
z match {
case x: A#T => x
}
问题是,scala无法识别在匹配的情况下A#t分别是Int或Boolean
严格地说,它不是。例如,你可以打电话
get[Abstract](new Impl1)
在这种情况下,A#T
是抽象的#T
,它既不是Int
也不是布尔的
。或
get(throw new Exception)
所以你得到了Nothing#T
(Nothing
问题是,scala无法识别在匹配的情况下A#t分别是Int或Boolean
严格地说,它不是。例如,你可以打电话
get[Abstract](new Impl1)
在这种情况下,A#T
是Abstract#T
,既不是Int
也不是Boolean
,或者
get(throw new Exception)
因此,您得到了Nothing#T
(Nothing,因此即使scala似乎无法检查此约束,在这种情况下,使用替代是否可以保存,即它是否从未抛出CastClassException
(或者匹配
没有失败)?在这种特殊情况下,您不会得到ClassCastException
,但一般来说,您应该避免使用asInstanceOf
这样的必要性,因此,即使scala似乎无法检查此约束,在这种情况下使用asInstanceOf
是否省力,即它是否从不抛出CastClassException
(或匹配
未失败)?在这种特殊情况下,你不会得到ClassCastException
,但一般来说,你应该避免使用来代替
,你想用这样的代码实现什么?隐喻I:在我的用例中,我有一大堆问题来定义它们的结果类型。然后我有一个函数calculateResponse[Q所以你会在各种问题上进行模式匹配,不是吗?是的。在Haskell中,这是因为正确地推断了类型。我只是想知道这在Scala中是否也可能,或者我是否应该使用其他设计模式。现在,我通过制作一个答案特征并只制作函数calculateResponse(Q:问题)来解决这个问题:Result
。这不是类型安全的,但可能少做一些类型黑客是正确的答案。你想用这样的代码实现什么?隐喻I:在我的用例中,我有一大堆问题定义它们的结果类型。然后我有一个函数calculateResponse[Q所以你会在各种问题上进行模式匹配,不是吗?是的。在Haskell中,这是因为正确地推断了类型。我只是想知道这在Scala中是否也可能,或者我是否应该使用其他设计模式。现在,我通过制作一个答案特征并只制作函数calculateResponse(Q:问题)来解决这个问题:Result
。这不是类型安全的,但可能少做一些类型黑客是正确的答案。