我真的对理论上的答案更感兴趣。所以也许我应该问 int * int vs int + int。我将 int * int 解释为一个元组,其中 int 的基数平方为组合数。
2 回答
如果想进一步了解理论,可以搜索产品类型(元组是基本情况,记录是标签产品)和求和类型(Choice<..>
F#中的类型是基本情况,可区分联合是标签和类型)的信息)。
集合论的解释是乘积类型对应于集合的乘积,而总和类型对应于一个联合(更准确地说是一个不相交的联合——因为它们被标记了)。
因此,假设这[| T |]
是一个表示类型值的集合T
:
[| T 1 * T 2 |] = { (v 1 , v 2 ) | v 1 ∈ [| T 1 |], v 2 ∈ [| T 2 |] }
[| T 1 + T 2 |] = { (1, v) | v ∈ [| T 1 |] } ∪ { (2, v) | v ∈ [| T 2 |] }
一个更简单的+
操作版本将只是联合,但只有当两种类型具有不同的值时才有意义(因此您可以在没有标签的情况下进行区分):
[| T 1 + T 2 |] = [| T 1 |] ∪ [| 2 | ]
这实际上很有趣,因为您会发现许多标准代数定律也适用于类型。例如,分配性说:(a + b) * c = (a * c) + (b * c)
. 这也适用于类型,这意味着以下两个是等价的:
type AorB = A of int | B of string // int + string
type AorBandC = AorB * float // (int + string) * float
type AandC = int * float // int * float
type BandC = string * float // string * float
type AandCorBandC = AC of AandC | BC of BandC // (int * float) + (string * float)
您可以编写一对将在 和 的值之间映射的AorBandC
函数AandCorBandC
。事实上,你可以更狂野甚至区分类型。这有点疯狂,但你要求一个理论:http ://www.cs.nott.ac.uk/~txa/publ/jpartial.pdf
是的,记录类型就像元组类型一样,只是它们的元素有名称。正如元组类型的 F#/ML 语法所暗示的,类型的元组A * B * C * ...
具有 |A| * |B| * |C| * ... 可能的值。同样,歧视联合| N1 of A | N2 of B | ...
有 |A|也是正确的。+ |B| + ... 可能的值。你没有提到它,但函数类型对应于幂:A -> B
有 |B| |一个| 居民。