在函数式编程中定义函数pointfree-style。有什么缺点/专业人士?

时间:2011-09-09 21:29:56

标签: f# functional-programming ocaml pointfree

每次我写一些表格

let scorePopulation f population =
  Array.map (fun i -> f i) population

我最后问自己,如果不是我写得更好

let scorePopulation f =
  Array.map (fun i -> f i)

代替。以第一种形式而不是第二种形式写作是否有任何优势?

另外,您如何以第一种形式和第二种形式调用函数定义?

6 个答案:

答案 0 :(得分:12)

你可以走得更远:

let scorePopulation = Array.map

就优缺点而言,我认为主要关注点通常是可读性。有时,当所有参数都存在时,更容易理解函数的作用。其他时候,您不需要组成无关的变量名称这一事实胜出。

答案 1 :(得分:10)

实际上,优点和缺点是相同的:命名。

原因是Phil Karlton的老话:

  

计算机科学只有两个难题。缓存失效和命名事物。

如果命名事情很难(即昂贵),那么名字不应该浪费在无关紧要的事情上。相反,如果某个东西有名字,那么这很重要。

无点样式允许您省略名称。

专业人士认为,它允许您省略不相关的名称。

这是因为它允许您省略相关的名称。

答案 2 :(得分:7)

我认为部分应用程序是函数式编程的一个好处。为什么不利用它呢?它导致更少的冗余。

要记住的另一件事是value restriction[MSDN]。没有参数的部分应用函数是函数。真正的函数可以推广,但值不能。

答案 3 :(得分:6)

您应该能够在第一个和第二个示例中以相同的方式调用它。此技术通常称为point-free style.

可能会更好。它更短,所以默认是加号。我同意上面链接中的这个警告:

  

当高阶函数链接在一起时,它会变得更难   精神上推断表达的类型。一个人的心理线索   表达式的类型(显式函数参数和数量   争论失踪。

您也失去了为参数提供有意义名称的机会,这有时可能有助于理解。

答案 4 :(得分:5)

就我个人而言,我讨厌无点风格,我总觉得它不可读。正如其他人提到的那样,

  

您也失去了为参数赋予有意义名称的机会,   这有时可能有助于理解。

总的来说,如果我在左边定义一个命名函数,我通常希望看到列出的所有'预期'参数。 (相比之下,部分应用程序对于匿名调用站点和本地lambda非常有用,但是我在编写顶级代码时更喜欢显式/文档 - 范围越大,'软件工程'关注的问题就越多。)

正如其他人所提到的,如果你摆脱了泛型函数中的所有参数,那么'价值限制'就会启动,这是一个技术限制,也很少会阻止F#中的无点样式。

答案 5 :(得分:2)

我经常提供参数,即使我可以省略它以便清楚。当我省略参数时,通常是因为函数体立即显而易见: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)

我发现第一个更清楚了。这里的好处来自于直观的高阶运算符,例如电池中提供的|>