F#跳过范围操作员

时间:2015-03-29 15:45:58

标签: f#

我正在尝试在F#中生成日期(时间段)列表,我在(F# generate a sequence/array of dates)找到了我的答案,它完美无缺。

但是,我不能围绕(+)静态成员的定义进行包装。

静态成员(+)(d:日期时间,跨度包装)= ...

特别是Span包装部分。我甚至重写的是:

静态成员(+)(d:日期时间,包装:跨度)= ...

即使它编译(fsi)它也不起作用。

只有当我重写它以匹配原始语法时,它才能按预期工作。

我查看了MSDN文档以及我所拥有的一些F#书籍,但我找不到任何解释(+)运算符特定语法的内容。

2 个答案:

答案 0 :(得分:5)

对于上下文,这是原始示例:

type Span = 
  | Span of TimeSpan
  static member (+) (d:DateTime, Span wrapper) = d + wrapper
  static member Zero = Span(new TimeSpan(0L))

(+)中,作者直接在参数上使用模式匹配。这意味着包装器的类型为TimeSpan,而d + wrapperDateTimeTimeSpan之间的操作

该示例在以下详细形式中看起来更清晰:

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构造。在任何情况下,都没有与运算符和类型相关的特殊内容 - 它只是人们在定义包装器时有时使用的命名技巧。