【问题标题】:Why this f# code does not compile?为什么这个 f# 代码不能编译?
【发布时间】:2017-09-27 19:42:27
【问题描述】:

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

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

【问题讨论】:

  • 你得到什么错误?
  • (true, item) "这个表达式应该有类型 'string -> bool * int' 但这里有类型 ''a * 'b' "。编译器假定生成的函数采用一个参数。我想了解为什么会做出这个决定。

标签: f#


【解决方案1】:

通过扩展代码更容易解​​释,因此函数传递/组合更少。

让我们删除 compose 运算符 >> 并改用管道 |>,添加一个显式的 aString 参数:

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

现在让我们使用fun 而不是function 和一个显式参数x

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 aStringf 函数,只应用了一个字符串。因为柯里化,这个表达式的类型是string -> bool * int。我在上面的代码中添加了一个类型注释来证明这一点。在产生bool * int 的结果之前,需要提供另一个字符串。

【讨论】:

  • 感谢您的解释!但是为什么编译器不选择以下代码来等效:let helper (f : string -> string -> bool * int) aString bString = f aString bString |> function | (true, item) -> Some item | (false, _) -> None
  • 因为它不等价! :) 它不遵循语言的语法规则将它们视为同一事物。 >> 无法动态计算出要在静态类型系统中传递多少参数。为了保持相同的结构,您可以定义运算符 let (>>+) f g a b = f a b |> g 并改用它。但是,请不要这样做,因为这会造成不必要的混乱。
  • 终于明白了)>> 运算符是用一个参数定义的 这是我期望它工作的方式:let (>>+) f g x y = f x y |> g let helper (f : string -> string -> bool * int) = f >>+ function | (true, item) -> Some item | (false, _) -> None 谢谢!
【解决方案2】:

f 接受两个参数。 >> 只包含一个参数。你可以这样写来编译它:

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

或者您可以在函数签名本身中包含第一个参数,如下所示:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 2014-03-01
    • 2010-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多