使用Either的别名在Scala中写入类似联合类型的Ceylon

0__*_*0__ 9 types scala

随着Ceylon 1.0的发布,一些人正在讨论联合类型的有用性.我想知道你如何简洁地编写以下代码:

String test(String | Integer x) {
  if (x is String) {
     return "found string";
  } else if (x is Integer) {
     return "found int";
  }
  return "why is this line needed?";
}

print(test("foo bar"));  // generates 'timeout'... well, whatever
Run Code Online (Sandbox Code Playgroud)

......在斯卡拉?我的想法是这样的:

type | [+A, +B] = Either[A, B]

object is {
  def unapply[A](or: Or[A]): Option[A] = or.toOption

  object Or {
    implicit def left[A](either: Either[A, Any]): Or[A] = new Or[A] {
      def toOption = either.left.toOption
    }
    implicit def right[A](either: Either[Any, A]): Or[A] = new Or[A] {
      def toOption = either.right.toOption
    }
  }
  sealed trait Or[A] { def toOption: Option[A] }
}

def test(x: String | Int) = x match {
  case is[String](s) => "found string"   // doesn't compile
  case is[Int   ](i) => "found int"
}
Run Code Online (Sandbox Code Playgroud)

但模式提取器无法编译.有任何想法吗?

我知道有一些类似的问题存在一些有效的答案,但我特别想知道是否可以使用类型别名Either和提取器.即使定义了除类型之外的新类型Either,解决方案也应该允许详尽的模式匹配.

0__*_*0__ 0

根据记录,Dotty 有联合类型,因此示例是

def test(x: String | Int): String = x match {
  case _: String => "found string"
  case _: Int    => "found int"
}

println(test("foo bar"))
Run Code Online (Sandbox Code Playgroud)

斯卡斯蒂链接