F# - Int32.TryParse 的部分应用

F# - Partial application of a Int32.TryParse

我正在尝试这样做

let TryParseAnyNumberStyle = Int32.TryParse(style= NumberStyles.Any, privider=CultureInfo.CurrentCulture)

但是编译器报错

The member or object constructor 'TryParse' does not take 0 argument(s). An overload was found taking 2 arguments.

我解决它的唯一方法是

  let TryParse numStyle culture (str:string) = 
    match Int32.TryParse(str, numStyle, culture) with
        | true, v -> true, v
        | _ -> false, 0

  let TryParseAnyNumberStyle = TryParse NumberStyles.Any CultureInfo.CurrentCulture

为什么编译器不喜欢我最初的部分应用程序?

请记住,由于您调用的是静态方法,因此我们不是在谈论 partial application, but overload resolution。关键的区别在于,部分应用程序需要一个带有柯里化参数和至少为两个元数的函数,而重载解析将由编译器对采用元组参数的方法执行。

下面是部分应用 F# 加法运算符的简单示例,将元数(柯里化参数的数量)从两个减少到一个:

let add = (+)
// val add : (int -> int -> int)
let add1 = (+) 1
// val add1 : (int -> int)

TryParse 方法有两个重载,分别带有两个和四个元组参数。

public static bool TryParse(string s, out int result)
public static bool TryParse(string s, System.Globalization.NumberStyles style, System.IFormatProvider provider, out int result)

对于out参数,F#编译器会进行特殊的语法转换,因此您实际上需要提供一个或三个元组参数才能成功解析重载。通过指定第一个字符串输入参数,您的定义将按预期工作:

open System
open System.Globalization
let tryParseAnyNumberStyle s =
    Int32.TryParse(s, 
        style=NumberStyles.Any, 
        provider=CultureInfo.CurrentCulture )
// val tryParseAnyNumberStyle : s:string -> bool * int