我在许多情况下都遇到了 F# 的困难。我相信我没有掌握一些基本概念。我希望有人可以跟踪我的推理并找出我遗漏的(可能很多)东西。

假设我正在使用 Xunit。我想做的是,提供两个列表,成对应用 Assert.Equal 方法。例如:

Open Xunit
let test1 = [1;2;3]
let test2 = [1;2;4]
List.map2 Assert.Equal test1 test2

编译器提示函数 Equal 没有一个参数。据我所知,map2 不应该提供 2 个参数吗?

作为完整性检查,我在 f#immediate 中使用以下代码:
let doequal = fun x y -> printf "result: %b\n" (x = y)
let test1 = [1;2;3]
let test2 = [1;2;4]
List.map2 doequal test1 test2;;

这似乎是相同的。 doequal 是一个 lambda,它采用 两个通用参数 并返回 单位 List.map2 将每个参数成对地传递给 lambda,我得到的输出正是我所期望的:
result: true
result: true
result: false

那么什么给呢?来源显示 Xunit.Equal 具有签名 public static void Equal<T>(T expected, T actual) 。为什么我的参数不能直接映射到方法签名上?

编辑一个
我认为两个变量x和y与元组(x,y)可以互换地构造和解构。所以我尝试了两种选择并得到了不同的结果。似乎第二个可能比第一个更远。
List.map2 Assert.Equal(test1, test2)编译器现在提示“连续的参数应该是分隔的空格或元组”
List.map2(Assert.Equal(test1, test2))编译器现在提示“无法确定唯一的重载方法......可能需要类型注释”

最佳答案

我认为部分问题来自混合方法(OO 风格)和函数(FP 风格)。

  • FP 样式函数具有多个由空格分隔的参数。
  • OO 风格的方法具有用逗号分隔的括号和参数。
  • 其他 .NET 库中的方法总是使用“元组”语法调用(尽管实际上与元组略有不同),并且元组被认为是一个参数。

  • F# 编译器尝试处理这两种方法,但偶尔需要一些帮助。

    一种方法是用 FP 函数“包装”OO 方法。
    // wrap method call with function
    let assertEqual x y = Assert.Equal(x,y)
    
    // all FP-style functions
    List.map2 assertEqual test1 test2
    

    如果不创建辅助函数,则在使用 lambda 调用“内联”方法时,通常需要将多个函数参数转换为一个元组:
    List.map2 (fun x y -> Assert.Equal(x,y)) test1 test2
    

    当您在一行中混合方法和函数时,您经常会收到“连续的参数应该分开”错误。
    printfn "%s" "hello".ToUpper()
    // Error: Successive arguments should be separated
    // by spaces or tupled
    

    这告诉你编译器有问题,需要一些帮助!

    您可以在方法调用周围使用额外的括号解决此问题:
    printfn "%s" ("hello".ToUpper())  // ok
    

    或者有时,使用反向管道:
    printfn "%s" <| "hello".ToUpper() // ok
    

    无论如何,包装方法通常值得一试,以便您可以交换参数以使其更适合部分应用:
    // wrap method call with function AND swap params
    let contains searchFor (s:string) = s.Contains(searchFor)
    
    // all FP-style functions
    ["a"; "b"; "c"]
    |> List.filter (contains "a")
    

    请注意,在最后一行中,我必须使用括号使 contains "a" 优先于 List.filter

    关于f# 签名匹配解释,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27693258/

    10-13 01:37