Haskell 中的闭包和列表推导式
我现在正在使用 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 程序员会走哪条路呢? 这两种解决方案有什么区别?
I'm playing around with Haskell at the moment and thus stumbled upon the list comprehension feature.
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?
What are the differences between these two solutions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
惯用的 Haskell 是
filter (> 4) [1..7]
请注意,您没有捕获闭包中的任何词法范围,而是使用分段运算符。也就是说,您想要部分应用
>
,哪些运算符部分会立即为您提供。列表推导式有时很有吸引力,但通常的看法是它们的伸缩性不如通常的高阶函数套件(相对于更复杂的组合的“伸缩性”)。当然,这种风格决定在很大程度上是主观的,所以 YMMV。Idiomatic Haskell would be
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.如果元素有些复杂并且需要通过模式匹配来过滤它们,或者映射部分对于 lambda 抽象来说太复杂,而 lambda 抽象应该很短(或者我是这么认为),或者如果必须处理,则列表推导式会派上用场与嵌套列表。在后一种情况下,列表理解通常比替代方案更具可读性(无论如何对我来说)。
例如:
但对于您的示例,
(>4)
部分是编写(\a -> a > 4)
的一种非常好的方式,并且因为您仅将其用于过滤,所以大多数人会更喜欢 ANThony 的解决方案。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. In the latter case, a list comprehension is often more readable than the alternatives (to me, anyway).
For example something like:
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.