代数类型
代数类型是通过将类型视为代数来操作类型而生成的类型 它们处理的操作包括Union、Intersection、Diff、Complement等 普通类只能进行Union,其他操作会导致类型错误
联合(Union)
联合类型可以为类型提供多种可能性。顾名思义,它们是由"或"运算符生成的
一个典型的 Union 是 Option
类型。Option
类型是 T 或 NoneType
补丁类型,主要表示可能失败的值
IntOrStr = Int or Str
assert dict.get("some key") in (Int or NoneType)
Option T = T or NoneType
请注意,联合类型是可交换的,但不是关联的。也就是说,X or Y or Z
是(X or Y) or Z
,而不是X or (Y or Z)
允许这样做会导致,例如,Int 或 Option(Str)
、Option(Int) 或 Str
和Option(Int or Str)
属于同一类型
路口
交集类型是通过将类型与 and
操作组合得到的
Num = Add and Sub and Mul and Eq
如上所述,普通类不能与"and"操作结合使用。这是因为实例只属于一个类
差异
Diff 类型是通过 not
操作获得的
最好使用 and not
作为更接近英文文本的符号,但建议只使用 not
,因为它更适合与 and
和 or
一起使用
CompleteNum = Add and Sub and Mul and Div and Eq and Ord
Num = CompleteNum not Div not Ord
True = Bool not {False}
OneTwoThree = {1, 2, 3, 4, 5, 6} - {4, 5, 6, 7, 8, 9, 10}
补充
补码类型是通过 not
操作得到的,这是一个一元操作。not T
类型是 {=} not T
的简写
类型为"非 T"的交集等价于 Diff,类型为"非 T"的 Diff 等价于交集
但是,不推荐这种写法
# 非零数类型的最简单定义
NonZero = Not {0}
# 不推荐使用的样式
{True} == Bool and not {False} # 1 == 2 + - 1
Bool == {True} not not {False} # 2 == 1 - -1
真代数类型
有两种代数类型: 可以简化的表观代数类型和不能进一步简化的真实代数类型
"表观代数类型"包括 Enum、Interval 和 Record 类型的 or
和 and
这些不是真正的代数类型,因为它们被简化了,并且将它们用作类型说明符将导致警告; 要消除警告,您必须简化它们或定义它们的类型
assert {1, 2, 3} or {2, 3} == {1, 2, 3}
assert {1, 2, 3} and {2, 3} == {2, 3}
assert -2..-1 or 1..2 == {-2, -1, 1, 2}
i: {1, 2} or {3, 4} = 1 # 类型警告: {1, 2} 或 {3, 4} 可以简化为 {1, 2, 3, 4}
p: {x = Int, ...} and {y = Int; ...} = {x = 1; y = 2; z = 3}
# 类型警告: {x = Int, ...} 和 {y = Int; ...} 可以简化为 {x = Int; y = 整数; ...}
Point1D = {x = Int; ...}
Point2D = Point1D and {y = Int; ...} # == {x = Int; y = Int; ...}
q: Point2D = {x = 1; y = 2; z = 3}
真正的代数类型包括类型"或"和"与"。类之间的"或"等类属于"或"类型
assert Int or Str == Or(Int, Str)
assert Int and Marker == And(Int, Marker)
Diff, Complement 类型不是真正的代数类型,因为它们总是可以被简化