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
。这不是类型安全的,但可能少做一些类型黑客是正确的答案。