为什么这个f#代码不能编译?

为什么这个f#代码不能编译?,f#,F#,我希望它是一个接受两个字符串并返回整数选项的函数 let helper (f : string -> string -> bool * int) = f >> function | (true, item) -> Some item | (false, _) -> None f接受两个参数>>仅使用单个参数。您可以通过以下方式进行编译: let helper(f:string->string->bool*int)= 乐趣a->f a>>功能

我希望它是一个接受两个字符串并返回整数选项的函数

 let helper (f : string -> string -> bool * int) = f >> function
    | (true, item) -> Some item
    | (false, _) -> None

f
接受两个参数<代码>>>仅使用单个参数。您可以通过以下方式进行编译:

let helper(f:string->string->bool*int)=
乐趣a->f a>>功能
|(真,项目)->某些项目
|(假)->无
或者您可以在函数签名本身中包含第一个参数,如下所示:

let helper(f:string->string->bool*int)a=fa>>函数
|(正确,项目)->某个项目
|(假)->无

通过将代码展开,减少函数传递/组合,这更容易解释

让我们删除compose操作符
>
并使用管道
|>
,添加显式的
aString
参数:

let helper (f : string -> string -> bool * int) aString =
    f aString |> function
    | (true, item) -> Some item
    | (false, _) -> None
现在让我们使用
fun
而不是带有显式参数
x
function

let helper (f : string -> string -> bool * int) aString =
    f aString
    |> fun x ->
        match x with
        | (true, item) -> Some item
        | (false, _) -> None
现在,让我们通过内联
fun
,将管道全部移除:

let helper (f : string -> string -> bool * int) aString =
    match (f aString : string -> bool * int) with
    | (true, item) -> Some item
    | (false, _) -> None

此代码与您开始使用的代码相同
f aString
是只应用一个字符串的
f
函数。由于使用了curry,此表达式的类型为
string->bool*int
。我在上面的代码中添加了一个类型注释来证明这一点。在生成
bool*int

的结果之前,需要提供另一个字符串。您会得到什么错误?(true,item)“此表达式的类型应为'string->bool*int',但此处的类型为'a*'b'。编译器假定结果函数接受一个参数。我想了解为什么做出这个决定。谢谢你的解释!但是为什么编译器不选择以下代码作为等价代码:
let helper(f:string->string->bool*int)aString bString=f aString bString |>function |(true,item)->某些项|(false,|)->None
,因为它不等价!:)它没有遵循语言的语法规则将它们视为同一事物。
>
无法动态计算在静态类型系统中要传递多少个参数。为了保持相同的结构,您可以定义操作符
let(>>+)fgab=fab |>g
,并使用它。但是,请不要这样做,因为这会造成不必要的混乱。终于明白了)>>操作符是用一个参数定义的,这是我期望它工作的方式:
let(>+)fGxy=fXy |>glet助手(f:string->string->bool*int)=f>+函数|(true,item)->某个item |(false,|->无
谢谢!