Scala中求和类型的简短表示

时间:2019-03-23 21:33:06

标签: scala

Scala中求和类型的缩写吗?

例如:

产品类型-(整数,双精度)

功能类型-(整数=>双精度)

总和类型-?

2 个答案:

答案 0 :(得分:4)

不,在Scala中没有用于定义 sum类型的语法糖。实际上,Scala在其类型系统中没有 sum类型作为独特功能。它们需要以某种方式进行编码,最广泛使用的编码是封闭的子类型层次结构,即 sum类型

A = B + C

编码为

sealed trait A

final class B extends A
final class C extends A

请注意,Scala也没有针对产品类型的语法糖。您提到的语法适用于元组类型,而不适用于产品类型。元组类型只是产品类型的许多不同类别之一。例如。 case class es 是另一类产品类型。

还要注意,Scala在其类型系统中也没有产品类型的概念。它们被编码为参数类型,它们是ProductN类型之一的子类型。即元组类型 (A, B)实际上是

的语法糖。
Tuple2[A, B]

定义为

final case class Tuple2[+A, +B](_1: A, _2: B) extends Product2[A, B] with Product with Serializable

当然,类和特征可以看作是记录的变体,因此在某种意义上,Scala中的每种类型都可以看作是产品类型,这就是为什么对它们进行编码如此容易的原因。

答案 1 :(得分:3)

在Scala中,求和类型构造函数由scala.util.Either给出。如果您需要两种以上类型的标记总和(例如ABC),那么通常可以创建自定义的密封特征:

sealed trait AorBorC

case class CaseA(a: A) extends AorBorC
case class CaseB(b: B) extends AorBorC
case class CaseC(c: C) extends AorBorC

然后使用模式匹配。

当然,您可以根据需要定义快捷方式:

type +[A, B] = Either[A, B]
type \/[A, B] = Either[A, B]

,然后以后缀符号A + BA \/ B使用它们。

您也可以从ScalaZ使用\/


util.Either确实是here所述的副产品:

  • 格式:对于任何两个A, B类型,您都可以形成Either[A, B]类型(没有限制)
  • 简介:如果a: Ab: B,则Left(a)Right(b)均为类型Either[A, B]的值。
  • 消除:如果使用e: Either[A, B],则可以使用常规模式匹配将两种情况折叠为单一类型C

    e match {
      case Left(a) => c1(a) // assuming `c1(a): C`
      case Right(b) => c2(b) // assuming `c2(b): C`
    }
    

    还有fold

    e.fold(c1, c2)
    

    基本上相同,并且还会产生类型为C的值。含义应该很清楚:

    Left(a).fold(c1, c2) == c1(a)
    Right(b).fold(c1, c2) == c2(b)
    

这确实是AB的和类型,因为对于任何其他类型C和任意两个函数c1: A => C,{ {1}}有一个函数c2: B => C,上面的两个标识都具有该函数,这正是定义副产品所需的通用属性。