Scala在F#中对应的区分并集是什么?

8xiog9wr  于 2023-01-30  发布在  Scala
关注(0)|答案(2)|浏览(196)

如何将F#中的Discriminated Union转换为Scala:

type Expr =
    | Val     of String
    | Integer of Int32
    | Lower   of Expr * Expr
    | Greater of Expr * Expr
    | And     of Expr * Expr
    | Or      of Expr * Expr

有一个类似的帖子谈论ADTs in F# and Scala,但这似乎不是我所追求的。

ioekq8ef

ioekq8ef1#

scala中的继承就是这样做的(可能很不幸,因为它比较冗长)

sealed trait Expr
case class Val(s: String) extends Expr
case class Integer(i: Int) extends Expr
case class Lower(left: Expr, right: Expr) extends Expr
case class Greater(left: Expr, right: Expr) extends Expr
...

您可以输入更多内容

sealed trait Expr[A]
case class Val(s: String) extends Expr[String]
case class Integer(i: Int) extends Expr[Int]
case class Lower[X](left: Expr[X], right: Expr[X])(implicit val ordering: Ordering[X]) extends Expr[Boolean]

模式匹配

def valueOf[A](expr: Expr[A]) : A = expr match {
   case Val(s) => s
   case Integer(i) => i
   case l @ Lower(a,b) => l.ordering.lt(valueOf(a), valueOf(b))
   ...
}

valueOf作为Expr中的方法可能会更好

sealed trait Expr[A] {def value: A}
case class Val(value: String) extends Expr[String]
case class Integer(value: Int) extends Expr[Int]
case class Lower[X: Ordering](left: Expr[A], right: Expr[A]) extends Expr[Bool] {
   def value = implicitly[Ordering[X]].lt(left.value, right.value)
}
...

几年后,因为这仍然得到一些投票现在,然后。
上面写的仍然有效,但是如果你使用Scala 3,它已经引入了枚举,这要方便得多。
声明现在可以是

enum Expr {
  case Val(s: String)
  case Integer(i: Int)
  case Lower(left: Expr, right: Expr)
}

或通用版本(带GADT)

enum Expr[A] {
  case Val(s: String) extends Expr[String]
  case Integer(i: Int) extends Expr[Int]
  case Lower[X: Ordering](
    left: Expr[X], 
    right: Expr[X]) extends Expr[Boolean]
}

用法与以前相同,只是各种构造函数不再位于顶级名称空间中,因此在创建和匹配时,必须编写Expr.Val,而不仅仅是Val(实际上,Scala 2中的习惯做法是,编写case时与我之前的做法稍有不同,以避免case也出现在顶级名称空间中)。简单的import Expr._将使名称再次直接可用。
最后,下面是@mcintyre321评论的一个迟来的回复:是的,当匹配不完全时会有警告。

n1bvdmb6

n1bvdmb62#

我完全同意Didier Dupont,但是如果您需要更高级别的抽象,在Scala中实现选项类型会给您一个很好的直观感受:

sealed trait Option[+E]

case class Some[+E]( element : E ) extends Option[E]
case object None extends Option[Nothing]

来源:https://mauricio.github.io/2013/12/25/learning-scala-by-building-scala-lists-part-3.html

相关问题