【问题标题】:F# Skip Range OperatorF# 跳过范围运算符
【发布时间】:2015-03-29 23:56:36
【问题描述】:

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

但是,我无法围绕 (+) 静态成员的定义展开讨论。

静态成员 (+) (d:DateTime, Span wrapper) = ...

尤其是 Span 包装部分。我什至重写为:

静态成员 (+) (d:DateTime, wrapper:Span) = ...

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

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

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

【问题讨论】:

    标签: f#


    【解决方案1】:

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

    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
    

    【讨论】:

    • 谢谢你们,现在说得通了。我希望我能接受这两个答案。他们还解释说,当我使用变体时,它不起作用,因为该函数一直在递归调用自身,而我从来没有等待足够长的时间等待堆栈溢出。
    【解决方案2】:

    这是一个非常微妙的句法技巧,您可以将其用于以下形式的类型定义:

    type MyNumber = MyNumber of int
    

    这定义了一个 type 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 构造。无论如何,操作符和类型并没有什么特别的关系——它只是人们在定义包装器时有时使用的命名技巧。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-21
      • 2011-01-17
      • 2012-04-20
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      • 1970-01-01
      • 2010-10-27
      相关资源
      最近更新 更多