F#: "type X = Y of Z" 的含义是什么?

3
在F#中,type X = Y of Z的意思是什么?具体而言,Y令牌有任何实际目的吗?如果我想表达X是由底层类型Z支持的类型,为什么需要在表达式中使用Y?
根据https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/keyword-referenceof 关键字用于表示以下一种情况:
1. 判别联合(Discriminated Unions) 2. 委托(Delegates) 3. 异常类型(Exception Types)
严格按照文档所述,type X = Y of Z不属于上述3个类别之一。
- 它不是判别联合语法,因为它缺少管道|字符。 - 它不是一个委托,因为缺少委托关键字。 - 它不是异常类型,因为缺少异常类型。
因此,尽管它在https://fsharpforfunandprofit.com/posts/conciseness-type-definitions/中广泛使用,但似乎type X = Y of Z是无效的语法。这非常令人困惑——文档是否不准确?
2个回答

4

与您的直觉相反,这种声明实际上是一个带有一个选项的歧视联合 - 正是如此。是的,只有一个选项的歧视性联合是完全合法的,有时用于类型安全或隐藏实现细节。

如果您不想在其中包含额外的Y,那也是合法的:

type X = Z

这被称为"类型别名"。与区分联合相比,它的优点是资源消耗(性能和内存),但其缺点是它不提供任何额外的安全性,因为在所有上下文中X最终等效且可互换于Z


2
请记住,如果 Z 不是先前定义的类型,则 type X = Z 实际上是一个空 case 的单例 DU。并不是很有用!但是有可能会意外地这样做,例如在 type Duration = TimeSpan 的情况下,如果您忘记了 open System - TheQuickBrownFox

3
这并不是联合类型语法,因为它缺少管道符号“|”。 在联合类型中可以省略第一个管道符号:“|”。
type DU = A of int | B

对于标准的多行定义,这种写法风格不好,但适用于单行情况。在您的示例中只有一个情况,因此完全可以省略管道符,这无疑会导致混淆。加上竖线可以提高清晰度:type X = | Y of Z

type X = Y of Z中,Y令牌是否具有任何实际目的?

Y用于区分不同情况,并用于匹配数据。如果未来可能出现更多情况,则使用这种搭建匹配框架是有意义的。如果您知道永远只会有一个情况,那么DU不是最合适的类型,因为记录 type X = { Y: Z } 是一种更简单的结构,可以达到同样的目的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接