【问题标题】:F# optional arguments and overloading alternativesF# 可选参数和重载选项
【发布时间】:2014-11-15 23:07:36
【问题描述】:

在我的 F# 应用程序中,我经常需要对字符串中的字符串执行不区分大小写的搜索,因此我创建了一个具有适当比较的函数:

let indexOf (str:string) (value:string) startIndex =
    match str.IndexOf(value, startIndex, StringComparison.OrdinalIgnoreCase) with
    | index when index >= 0 -> Some index
    | _ -> None

我不喜欢这样的事实,当我想从头开始搜索时,我必须将多余的 0 作为起始索引传递。

我对 F# 和函数式编程都比较陌生,所以我想知道从函数的角度来看,首选(最干净)的解决方案是什么?

  1. 创建两个版本:

    let indexOfFrom (str:string) (value:string) startIndex = (...)
    let indexOf str value = indexOfFrom str value 0
    
  2. 使用选项类型:

    let foundIndex = indexOf "bar foobar" "bar" (Some 4)
    
  3. 创建一个专用的可区分联合:

    type Position =
        | Beginning
        | StartIndex of index : int
    let foundIndex = indexOf "bar foobar" "bar" (Index 4)
    
  4. 将“indexOf”函数放在一个类型中并使用“经典”重载。

  5. 将“indexOf”函数放在一个类型中并使用 F# 可选参数。

【问题讨论】:

    标签: f# functional-programming


    【解决方案1】:

    如果您将功能定义为 F# 函数,那么我认为使用两个单独的函数(具有合理的描述性名称)可能是您拥有的最佳选择。所以我会选择你的第一个选项(我绝对更喜欢这个选项而不是仅仅为了这个单一目的定义一个有区别的联合):

    let indexOfFrom (str:string) (value:string) startIndex = (...)
    let indexOf str value = indexOfFrom str value 0
    

    另一种方法是将功能定义为类型的成员 - 然后您可以同时使用重载和 F# 可选参数,但您必须使用全名 String.IndexOf 访问它们。你可以这样写:

    type String =
      static member IndexOf(str:string, value:string, startIndex) = (...)
      static member IndexOf(str, value) = String.IndexOf(str, value, 0)
    

    或者,使用可选参数:

    type String =
      static member IndexOf(str:string, value:string, ?startIndex) = (...)
    

    哪个选项最好?

    • 如果您正在设计函数式 API(例如特定领域的语言),那么使用两个独立函数的选项可能是最佳选择。

    • 如果您的目标是设计一个不错的 F# API,那么我认为您的选项(多个函数)或可选参数是相当合理的。 Deedle 中大量使用函数,F# Charting 依赖于可选参数。

    • 使用重载的好处是该库也可以很好地用于 C#。因此,如果您正在考虑从 C# 调用库,这几乎是唯一的选择。

    【讨论】:

      【解决方案2】:

      我认为选项 1(带有 curried 函数)是最简单的。 Curried 函数在函数式编程中很常见。

      在选项 2 或 3 中,您仍然需要将附加参数传递给函数以便从头开始搜索

      选项 4 或 5 需要额外的开销来创建类型。这个简单的任务有点“矫枉过正”

      【讨论】:

        猜你喜欢
        • 2011-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-20
        • 2013-05-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多