每次我写一些形式的东西
let scorePopulation f population =
Array.map (fun i -> f i) population
我最终问自己我是否会写得更好
let scorePopulation f =
Array.map (fun i -> f i)
反而。与第二种形式相比,以第一种形式编写它有什么优势吗?
另外,您将如何调用第一种形式和第二种形式的函数定义?
每次我写一些形式的东西
let scorePopulation f population =
Array.map (fun i -> f i) population
我最终问自己我是否会写得更好
let scorePopulation f =
Array.map (fun i -> f i)
反而。与第二种形式相比,以第一种形式编写它有什么优势吗?
另外,您将如何调用第一种形式和第二种形式的函数定义?
你可以走得更远:
let scorePopulation = Array.map
就优点/缺点而言,我认为主要关注点通常是可读性。有时,当所有参数都存在时,更容易理解函数的作用。其他时候,您不需要编造无关变量名称这一事实胜出。
其实,利弊是一样的:命名。
原因是菲尔·卡尔顿的一句老话:
计算机科学中只有两个难题。缓存失效和命名事物。
如果命名事物很难(即昂贵),那么名称不应该浪费在不相关的事物上。相反,如果某物有名字,那么它很重要。
无点样式允许您省略名称。
优点是它允许您省略不相关的名称。
缺点是它允许您省略相关名称。
我认为部分应用是函数式编程的一个好处。为什么不利用它呢?它导致更少的冗余。
要记住的另一件事是值限制[MSDN]。没有参数的部分应用函数是函数值。真函数可以泛化,但值不能。
您应该能够在第一个和第二个示例中以相同的方式调用它。这种技术通常称为无点样式。
可能会更好。它更短,所以默认情况下这是一个加号。我同意上面链接中的这个警告:
随着高阶函数被链接在一起,在心理上推断表达式的类型会变得更加困难。对表达式类型(显式函数参数和参数数量)的心理暗示消失了。
你也失去了给参数一个有意义的名字的机会,这有时可能有助于理解。
我个人讨厌无点风格,我总是觉得它不可读。正如其他人提到的,
你也失去了给参数一个有意义的名字的机会,这有时可能有助于理解。
总体而言,如果我在左侧定义一个命名函数,我通常希望看到列出的所有“预期”参数。(相比之下,部分应用程序非常适合匿名呼叫站点和本地 lambda,但我更喜欢在编写顶级代码时更明确/文档 - 范围越大,“软件工程”问题就越多。)
正如其他人所提到的,如果您从泛型函数中删除所有参数,“值限制”就会生效,这是一个技术限制,也略微阻碍了 F# 中的无点样式。
我经常提供参数,即使为了清楚起见我可以省略它。当我省略参数时,通常是因为函数体立即表明:i)有一个省略的参数,ii)参数的性质是什么。例如,我觉得写
let f = function [] -> "empty" | x::_ -> "not empty"
代替
let f l = match l with [] -> "empty" | x::_ -> "not empty"
一个更有趣的例子是写
let f = List.map g |> List.fold_left h
代替
let f l = List.map g (List.fold_left h l)
我觉得第一个更清楚。这里的好处来自于直观的高阶运算符的可用性,例如|>
电池中提供的 。