简体   繁体   English

Haskell中的闭包和列表推导

[英]Closures and list comprehensions in Haskell

I'm playing around with Haskell at the moment and thus stumbled upon the list comprehension feature. 我此刻正在玩Haskell,因此偶然发现了列表理解功能。 Naturally, I would have used a closure to do this kind of thing: 当然,我会用一个闭包来做这种事情:

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

I still don't feel this language, so which way would a Haskell programmer go? 我仍然感觉不到这种语言,那么Haskell程序员会采用哪种方式? What are the differences between these two solutions? 这两种解决方案有什么区别?

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

Note that you are not capturing any of the lexical scope in your closure, and are instead making use of a sectioned operator. 请注意,您没有捕获闭包中的任何词法范围,而是使用分段运算符。 That is to say, you want a partial application of > , which operator sections give you immediately. 也就是说,您需要部分应用> ,哪些操作员部分会立即为您提供。 List comprehensions are sometimes attractive, but the usual perception is that they do not scale as nicely as the usual suite of higher order functions ("scale" with respect to more complex compositions). 列表理解有时是有吸引力的,但通常的看法是它们不像通常的高阶函数套件那样精确地缩放(对于更复杂的组合,“缩放”)。 That kind of stylistic decision is, of course, largely subjective, so YMMV. 当然,这种风格决定在很大程度上是主观的,所以YMMV。

List comprehensions come in handy if the elements are somewhat complex and one needs to filter them by pattern matching, or the mapping part feels too complex for a lambda abstraction, which should be short (or so I feel), or if one has to deal with nested lists. 如果元素有点复杂并且需要通过模式匹配来过滤它们,或者映射部分对于lambda抽象感觉过于复杂(这应该很短(或者我觉得)),或者如果必须处理,那么列表推导会派上用场使用嵌套列表。 In the latter case, a list comprehension is often more readable than the alternatives (to me, anyway). 在后一种情况下,列表理解通常比替代方案更具可读性(无论如何)。

For example something like: 例如:

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

But for your example, the section (>4) is a really nice way to write (\\a -> a > 4) and because you use it only for filtering, most people would prefer ANthonys solution. 但是对于你的例子,部分(>4)是一种非常好的写入方式(\\a -> a > 4) ,因为你只使用它进行过滤,大多数人都更喜欢ANthonys解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM