Scala中求和类型的缩写吗?
例如:
产品类型-(整数,双精度)
功能类型-(整数=>双精度)
总和类型-?
答案 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
给出。如果您需要两种以上类型的标记总和(例如A
,B
,C
),那么通常可以创建自定义的密封特征:
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 + B
或A \/ B
使用它们。
您也可以从ScalaZ使用\/
。
util.Either
确实是here所述的副产品:
A, B
类型,您都可以形成Either[A, B]
类型(没有限制)a: A
和b: 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)
这确实是A
和B
的和类型,因为对于任何其他类型C
和任意两个函数c1: A => C
,{ {1}}有一个函数c2: B => C
,上面的两个标识都具有该函数,这正是定义副产品所需的通用属性。