列表推导式是 Haskell 的重要组成部分吗?

11

我在购买《实际的 Haskell》这本书之前查看了网上各种不同的 Haskell 资源。虽然该书非常出色,但是它似乎没有包含任何关于列表推导式的内容,而我在查看的各种网站中都看到了有关该主题的提及。这是否仅仅是因为列表推导式通常在编写良好的 Haskell 中未被使用的原因,还是由于其他更加复杂的原因呢?例如,这个奇怪的语法可能只是一些我尚未见过的操作符的混合体。


列表推导式在在线书籍第12章中简要讨论:http://book.realworldhaskell.org/read/barcode-recognition.html#x_iF1 - mipadi
5个回答

23

列表推导式在第12章中简要提到。

在Haskell中,我发现自己更经常地使用map和filter的组合而不是列表推导式,但在Python中,我更频繁地使用列表推导式。因此,我认为这部分内容与个人风格有关。

一旦您了解如何使用列表推导式的每个部分,那么在列表推导式方面还有什么需要学习的呢?您拥有输入、条件/保护以及返回列表的函数应用程序。我真的不认为书中需要一个大篇幅来讲解列表推导式。


1
我同意这里的观点,我很少使用列表推导式语法糖。 - jrockway
4
列表推导式只不过是一种语法糖...虽然如果它们被定义为任何 MonadPlus 而不仅仅是 [a] 的话,它们可能会更加有用... ;) - Dario
5
@Dario - 问而必得:http://hackage.haskell.org/trac/ghc/wiki/MonadComprehensions - Edward Kmett

17

Haskell定义了一个小的核心语言功能集,周围是一个丰富的语法选择集。列表推导式是其中一种选择,但它们提供的内容与RWH在整本书中建立直觉的单子糖也没有什么不同。在许多情况下,Haskell为相同的事情提供了两种句法,例如let vs. where,case和组合器导向编程风格,以及列表推导式和单子糖。

列表推导式最初被实现为单子推导式,这一事实在“98年大单态化革命”(也称为Haskell '98)中发生了变化。实际上,在.NET语言中设计LINQ的灵感很大程度上来自于较旧的单子推导式设计。列表推导式可能比它们目前的功能更加通用,但它们被故意砍掉了以使其产生更易于理解的错误消息。

在有限的纸张数量中,您必须选择强调哪些材料,RWH在大部分时间内避免谈论它们,以便您不会陷入将列表视为任何特殊东西的陷阱。

话虽如此,在第12章中简要提到了它们。到那个时候,已经建立了足够的直觉概念,它们并不是真正的危险。

最终,这本书的名字是《实用 Haskell》。它想要教你好的实用编程技术。一些Haskeller(并非全部)避免使用列表推导式,因为符号不具有可扩展性,并且因为最终您可能希望回头修改单子变换器或其他东西,并且会重写整个推导式代码段以符合单子样式。

[更新:现在GHC已经重新获得单子推导式,所以这个反对意见并不像以前那么强烈了。您可以从它们中获得一些有趣的新功能。]


8
列表推导式主要出现在小型列表处理示例中,其中许多旨在明显具有数学味道。当您开始涉足像《Real World Haskell》所涵盖的较大应用程序时,列表处理在代码中所占比例要小得多。正如所指出的那样,使用 mapfilterfoldzip 等与使用列表推导式一样方便。

因此:

  • 在实际的Haskell程序中,只有很少一部分代码处理列表。

  • 使用列表推导式编写的列表处理Haskell代码只占相当小的一部分,并且有显著优势的情况很少。

我编写的几乎所有列表推导式都会生成成对的列表。但是,我不确定是否应该从中读取任何内容。


5
列表推导式是绑定列表(如单子的绑定)的语法糖。另一种相似的语法糖是do-notation。在我看来,它更好用,最大的优点是适用于所有单子。
如果没有列表推导式,我认为就会少学习一件事情,而且不会有任何损失(可以使用do-notation代替)。
支持列表推导式的论点是它会让用户更清楚地知道它是一个列表。在我看来,类型签名对此效果更好。

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接