scala - 与泛型匹配的模式

标签 scala

给定以下类模式匹配:

clazz match {
  case MyClass => someMethod[MyClass]
}

是否可以根据模式匹配结果以通用方式引用 MyClass?例如,如果我有多个 MyClass 的子类,我是否可以编写一个简单的模式匹配来将匹配的类型传递给 someMethod:

clazz match {
  case m <: MyClass => someMethod[m]
}

最佳答案

不幸的是,类型在 Scala 中并不是真正的一等公民。这意味着您不能对类型进行模式匹配。由于继承自 Java 平台的愚蠢类型删除,大量信息丢失。

我不知道是否有任何对此的改进请求,但这是我选择中最糟糕的问题之一,所以真的应该有人提出这样的请求。

事实是您需要传递证据参数,最多以隐式参数的形式传递。

我能想到的最好的是

class PayLoad

trait LowPriMaybeCarry {
   implicit def no[C] = new NoCarry[C]
}
object MaybeCarry extends LowPriMaybeCarry {
   implicit def canCarry[C <: PayLoad](c: C) = new Carry[C]
}

sealed trait MaybeCarry[C]
final class NoCarry[C] extends MaybeCarry[C]
final class Carry[C <: PayLoad] extends MaybeCarry[C] {
   type C <: PayLoad
}

class SomeClass[C <: PayLoad]

def test[C]( implicit mc: MaybeCarry[C]) : Option[SomeClass[_]] = mc match {
   case c: Carry[_] => Some(new SomeClass[ c.C ])
   case _ => None
}

但我仍然无法让隐式工作:

test[String]
test[PayLoad]  // ouch, not doin it
test[PayLoad](new Carry[PayLoad])  // sucks

因此,如果您想避免严重的脑损伤,我会忘记该项目或寻找另一种语言。也许 Haskell 在这里更好?我仍然希望我们最终可以匹配类型,但我的希望很低。

也许 scalaz 的人想出了一个解决方案,他们几乎将 Scala 的类型系统利用到了极限。

关于scala - 与泛型匹配的模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5365787/

相关文章:

scala - 在 Scala 中做类似 Python 的 "import"的事情

scala - 用于单子(monad)的 K/Kestrel 组合器?

scala - flatten和flatMap(identity)之间有什么区别吗?

scala - 检查 var 是 Scala 中的哪个匿名函数

scala - 理解 `Monomorphism` Shapeless的例子

java - Scala 中从 "for"返回与 Java 中从 "for"返回不同

scala - 如何从编译器插件中找到 Scala 程序中的语句?

java - 在 Spark 中读取自定义序列文件

scala - 您将如何在 Scala 中实现缓存方面

scala - 如何在 Spark 中将 unix 时间戳转换为日期