Cha*_*dan 0 haskell function pointfree
我刚学会了Haskell中的无点样式,以及它如何帮助整理代码并使其更易于阅读.但有时他们可以使代码有点过于简洁.
所以,当我应该总是使用无点样式时,在什么情况下我应该绝对避免在Haskell中使用无点样式?
正如已经评论过的那样,这是一个品味问题,并且总是存在两种风格同样适合的边缘情况(或者,实际上,部分指向的版本是最好的).但是,在某些情况下,它足够清楚:
如果尖锐的表达式可以像这样减少η,那么通常这样做是个好主意.
f x = g (h x)
Run Code Online (Sandbox Code Playgroud)
应该写得更好
f = g . h
Run Code Online (Sandbox Code Playgroud)如果要在接受某些函数参数之前记忆一些计算,则必须将这些参数保留在范围之外.例如,
linRegression :: [(Double, Double)] -> Double -> Double
linRegression ps x = a * x + b
where a, b = -- expensive calculation of regression coefficients,
-- depending on the `ps`
Run Code Online (Sandbox Code Playgroud)
在性能方面不是最佳的,因为需要针对x接收到的每个值重新计算系数.如果你点免费:
linRegression :: [(Double, Double)] -> Double -> Double
linRegression ps = (+b) . (a*)
where a, b = ...
Run Code Online (Sandbox Code Playgroud)
这个问题不会出现.(也许GHC在某些情况下会自行解决这个问题,但我不会依赖它.)
尽管如此,最好还是指出它,但不是与x同一范围相同a,b而是由专用的lambda绑定:
linRegression :: [(Double, Double)] -> Double -> Double
linRegression ps = \x -> a * x + b
where a, b = ...
Run Code Online (Sandbox Code Playgroud)如果自由点版本实际上是长比点的版本,我不会用它.如果你需要引入一些技巧来使它像点flip和Monad (a->)实例一样,这甚至不会使它更短,那么它几乎肯定会比尖头版本更不易读.
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |