有没有办法在Scala中应用OR来键入绑定?

时间:2016-08-30 09:06:30

标签: scala generics types

在Java中,我们只能将AND限制应用于类型绑定:

public class <T extends Serializable & SomeThingDoable> MyClass{
    //...
}

但我们无法告诉Java持有 OR 限制。

Scala是否可以提供限制,以便可以将元素添加到集合中 iff 类型SomeType1 SomeType2

3 个答案:

答案 0 :(得分:1)

在保证类型安全的情况下,你无法做到这一点。

我的意思是,你可以做一个instance并在实例化类时抛出错误,但那很脏。

更好的解决方案是使用ADT(抽象数据类型):

sealed trait NaturalNumber
final case class Zero() extends NaturalNumber
final case class Next(i: NaturalNumber) extends NaturalNumber


object Main extends App {
    val a: NaturalNumber = Next(Zero())
    a match {
        case Zero() => "zero"
    }
}

进行穷举检查:

<console>:16: warning: match may not be exhaustive.

答案 1 :(得分:1)

我建议使用类似coproducts

的内容

另请注意,Dotty将对类型具有AND / OR内置限制。

答案 2 :(得分:0)

没有完全支持这种语言级别的构造,但正如@dveim指出的那样,我相信这很快就会到来。

如果您在考虑具体的实际用例时,您确实有一些选择。您可以使用(?i)\\([^()]*\\b([a-z]\\w*)\\b[^()]*\\),它具有表示此想法所需的所有构造(但不是类型绑定)。

或者,您可以使用类型类来实现此效果:

Either[SomeType1, SomeType2]

请原谅这个简单的例子,但你得到的是:

  • a sealed trait Or[T] { def someMethod(t: T): String } object Or { implicit object OrInt extends Or[Int] { def someMethod(t: Int): String = "int" } implicit object OrLong extends Or[Long] { def someMethod(t: Long): String = "long" } } object Test { import Or._ def test[T](value: T)(implicit or: Or[T]): String = or.someMethod(value) } 表示您可以限制其他人向sealed trait系列添加更多实例(除非他们可以编辑其定义的实际文件)
  • 一种很好的方式来指定您希望在两种不同情况下发生的功能