F#跳过范围运算符
我试图用F#生成日期(时间段)的列表,我在()找到了答案,它非常有效 但是,我不能围绕(+)静态成员的定义展开讨论 静态成员(+)(d:DateTime,Span包装器)= 特别是跨度包装部分。我甚至重新写了如下: 静态成员(+)(d:DateTime,包装器:Span)= 即使它编译(fsi),它也不起作用 只有当我重写它以匹配原始语法时,它才能按预期工作F#跳过范围运算符,f#,F#,我试图用F#生成日期(时间段)的列表,我在()找到了答案,它非常有效 但是,我不能围绕(+)静态成员的定义展开讨论 静态成员(+)(d:DateTime,Span包装器)= 特别是跨度包装部分。我甚至重新写了如下: 静态成员(+)(d:DateTime,包装器:Span)= 即使它编译(fsi),它也不起作用 只有当我重写它以匹配原始语法时,它才能按预期工作 我查看了MSDN文档以及我所拥有的一些F#书籍,但找不到任何东西解释(+)运算符的特定语法。对于上下文,以下是原始示例: type Spa
我查看了MSDN文档以及我所拥有的一些F#书籍,但找不到任何东西解释(+)运算符的特定语法。对于上下文,以下是原始示例:
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
这是一个非常微妙的语法技巧,可用于以下形式的类型定义:
type MyNumber = MyNumber of int
这定义了一个类型MyNumber
,它是一个使用构造函数包装的整数,该构造函数也被命名为MyNumber
。因此,我们定义了一个类型和一个同名的构造函数。我们可以使用不同的名称:
type MyNumberType = MyNumberCtor of int
提取值时,以下语法用于模式匹配。在这里,我们使用构造函数:
let getNumber (MyNumber n) = n
let getNumber (MyNumberCtor n) = n
以下语法是类型注释(使用类型名称):
在这里,我们不能用
n
,因为它是包装的值-所以我们必须使用模式匹配来提取它。从@pad的答案中可以看到,编写模式匹配的另一种方法是使用match
构造。在任何情况下,运算符和类型都没有什么特别的关系——这只是人们在定义包装器时有时使用的一种命名技巧。谢谢你们两位,现在这很有意义。我希望我能接受这两个答案。他们还解释说,当我使用变体时,它不起作用,因为函数一直递归地调用自己,我从来没有等待堆栈溢出足够长的时间。
let doNothing (n:MyNumber) = 1
let getNumber (n:MyNumberType) = 1