为什么要使用列表理解?

问题描述 投票:0回答:2

为什么使用列表理解而不是更实用的方法,例如

map (*2) [1..5]

我认为列表理解语法不是很直接,需要记住,并且在 Haskell 中是多余的语法和功能,因为你可以只用列表函数做它能做的一切。

我错了吗?有没有什么事情可以用列表理解来做,而用函数式方法却做不到?

list haskell functional-programming list-comprehension
2个回答
8
投票

你没有错,列表理解语法不是需要。但

do
表示法(顺便说一句,它以几乎相同的方式脱糖),或者简单的列表文字,甚至字符串文字都不是。您可以随时写
,而不是写
"Hello, World!"

       'H':'e':'l':'l':'o':',':' ':'W':'o':'r':'l':'d':'!':[]

更进一步,您还可能会问为什么我们不只用 lambda 演算/System F 编写程序,而不是用实际的编程语言。

你大概可以明白我的意思了:

你为什么要使用列表理解

– 因为它们简洁、美观,而且很容易理解其含义。

具体来说,我认为列表推导式很好地把对快速理解最有用的信息放在前面:例如,

[x*2 | x<-[1..5]]
通过眼睛解析为

  • [...
    好的,名单出来了
  • [x*2 ...
    好的,至少有一个条目具有
    x*2
    的形式(无论
    x
    是什么),即偶数。
  • [x*2 |...
    啊,所有条目都是偶数,在某些源上量化
  • [x*2 | x<-...
    好的,所以
    x
    是列表中每个条目的变化
  • [x*2 | x<-[1..5]
    对,所以具体使用的数字是
    [1..5]

我想说,在很多情况下,这确实是快速阅读时从最有趣到最不有趣的顺序。它基本上是从通过示例解释(或原型)您得到什么样的结果条目开始,然后再详细了解条目的不同之处。

极端相反的是命令式

forM [1..5] $ \x -> do
   return $ x*2

在这里,我们从“开始一个循环”和“循环这些数字”开始,这很好,因为它概述了即将发生的事情操作性,但对“外延”的含义知之甚少。结果。然后继续定义变量x等..

map

版本介于两者之间,具有使用无点语法的额外怪癖。各有其优点和缺点。

这三种风格都有各自的用例,具体取决于哪种情况最适合每种情况。


0
投票
|

引入的,返回首先用 | 分隔,新术语用逗号分隔,而不是分号或换行符。这使得它们很方便。顺便说一下,列表推导式可以与其他 monad 一起使用,使用扩展名 MonadCompressives 事后看来,我们应该将 do 块和列表推导式与一种类型的糖结合起来。我认为这两者背后的理性在于,do-blocks 首先是作为一种让新手更容易开始编写 Haskell 的方式,而列表表示法是对数学人的回应,他们希望受到集合构建表示法的启发而获得更多便利。人们往往会对糖上瘾,因此他们会要求更多。

© www.soinside.com 2019 - 2024. All rights reserved.