我正在尝试在F#中生成日期(时间段)列表,我在(F# generate a sequence/array of dates)找到了我的答案,它完美无缺。
但是,我不能围绕(+)静态成员的定义进行包装。
静态成员(+)(d:日期时间,跨度包装)= ...
特别是Span包装部分。我甚至重写的是:
静态成员(+)(d:日期时间,包装:跨度)= ...
即使它编译(fsi)它也不起作用。
只有当我重写它以匹配原始语法时,它才能按预期工作。
我查看了MSDN文档以及我所拥有的一些F#书籍,但我找不到任何解释(+)运算符特定语法的内容。
答案 0 :(得分:5)
对于上下文,这是原始示例:
type Span =
| Span of TimeSpan
static member (+) (d:DateTime, Span wrapper) = d + wrapper
static member Zero = Span(new TimeSpan(0L))
在(+)
中,作者直接在参数上使用模式匹配。这意味着包装器的类型为TimeSpan
,而d + wrapper
是DateTime
和TimeSpan
之间的操作
该示例在以下详细形式中看起来更清晰:
static member (+) (d:DateTime, span: Span) =
match span with
| Span wrapper ->
d + wrapper
答案 1 :(得分:4)
这是一个非常微妙的语法技巧,您可以使用以下形式的类型定义:
type MyNumber = MyNumber of int
这定义了类型 MyNumber
,这是一个使用构造函数包装的整数,也称为MyNumber
。因此,我们定义了一个同名的类型和构造函数。我们可以使用不同的名称:
type MyNumberType = MyNumberCtor of int
在提取值时,以下语法用于模式匹配。在这里,我们使用构造函数:
let getNumber (MyNumber n) = n
let getNumber (MyNumberCtor n) = n
以下语法是类型注释(使用类型名称):
let doNothing (n:MyNumber) = 1
let getNumber (n:MyNumberType) = 1
在这里,我们对n
做不了多少,因为它是包装值 - 所以我们必须使用模式匹配来提取它。正如您在@pad的答案中所看到的,编写模式匹配的另一种方法是使用match
构造。在任何情况下,都没有与运算符和类型相关的特殊内容 - 它只是人们在定义包装器时有时使用的命名技巧。