Haskell中的闭包和列表推导

时间:2011-10-04 17:17:30

标签: haskell coding-style closures list-comprehension

此刻我正在玩Haskell,因此偶然发现了列表理解功能。 当然,我会用一个闭包来做这种事情:

Prelude> [x|x<-[1..7],x>4] -- list comprehension
[5,6,7]
Prelude> filter (\x->x>4) [1..7] -- closure
[5,6,7]

我仍然感觉不到这种语言,那么Haskell程序员会采用哪种方式? 这两种解决方案有什么区别?

2 个答案:

答案 0 :(得分:10)

惯用的Haskell将是filter (> 4) [1..7]

请注意,您没有捕获闭包中的任何词法范围,而是使用了分段运算符。也就是说,您希望部分应用>,操作员部分会立即为您提供。列表理解有时是有吸引力的,但通常的看法是它们不像通常的高阶函数套件那样精确地缩放(对于更复杂的组合,“缩放”)。当然,这种风格决定在很大程度上是主观的,所以YMMV。

答案 1 :(得分:1)

如果元素有点复杂并且需要通过模式匹配来过滤它们,或者映射部分对于lambda抽象感觉太复杂(或者应该是简短的(或者我觉得)),或者如果一个,那么列表推导会派上用场必须处理嵌套列表。在后一种情况下,列表理解通常比替代方案更具可读性(无论如何)。

例如:

[ (f b, (g . fst) a) | (Just a, Right bs) <- somelist, a `notElem` bs, (_, b) <- bs ]

但是对于您的示例,(>4)部分是一种非常好的编写(\a -> a > 4)的方法,因为您只将它用于过滤,大多数人都更喜欢ANthonys解决方案。