【问题标题】:Count negative numbers in list using list comprehension使用列表推导计算列表中的负数
【发布时间】:2014-02-05 15:20:09
【问题描述】:

阅读 Bird & Wadler 撰写的“函数式编程简介”第一版,它使用了一种理论上的惰性语言和类似 Haskell 的语法。

习题 3.2.3 问:

使用列表推导,定义一个计算数字的函数 列表中的负数

现在,在这一点上,我们仍处于列表的表面。我假设的意图是只应使用当时已经引入的概念,而以下内容尚未被引入:

  • 计算列表长度的函数
  • 列表索引
  • 模式匹配,即 f (x:xs) = ...
  • 无限列表
  • 作用于列表的所有函数和运算符 - 除了一个例外 - 例如++、head、tail、map、filter、zip、foldr等

有哪些工具可用?

  • 返回数值列表最大元素的最大值函数
  • 列表推导式,可能有多个生成器表达式和谓词
  • 理解的输出不需要依赖于生成器表达式的概念,这意味着生成器表达式可用于控制生成列表的大小
  • 有限算术序列列表,即 [a..b] 或 [a, a + step..b]

我承认,我被难住了。显然,通过理解可以很容易地从原始列表中提取负数,但是如果没有长度或索引的概念,那么如何计算它们呢?

maximum 函数的可用性表明最终游戏是构造一个列表,其最大元素是负数的个数,该函数的最终结果是将最大值应用于该列表。

我要么错过了一些显而易见的东西,要么错过了一个聪明的把戏,我有一种可怕的感觉,它可能是前者。告诉我,你是怎么解决这个问题的?

【问题讨论】:

    标签: functional-programming


    【解决方案1】:

    我认为您可能假设了太多限制 - 获取过滤列表的长度对我来说似乎是一种显而易见的解决方案。

    几个替代方案,但都涉及使用您说没有引入的其他功能:

    sum [1 | x <- xs, x < 0]
    
    maximum (0:[index | (index, ()) <- zip [1..] [() | x <- xs, x < 0]])
    

    【讨论】:

      【解决方案2】:

      我的第一版旧版——非常泛黄的副本在练习 3.2.3 中附有注释:“这个问题需要 #(长度),它只在稍后出现”。这个故事的寓意是在设置练习时要更加小心。我目前正在完成第三版,其中包含每个问题的答案。

      顺便说一句,你有没有回答练习 1.2.1,它要求你写下所有的方法 square (square (3 + 7)) 可以简化为范式。原来有547种方式!

      【讨论】:

      • 嗯,这个答案来自一个比我预期的更权威的来源!​​
      • 在错误的输入键后展开:我很高兴我没有遗漏任何明显的东西 - 我正在使用文本作为复习,并且知道通常会使用的标准工具箱列表,但想在本书的教学法的背景下回答。我意识到虽然在 §2.3 中,您引入了字符串,并假设存在一个宽度函数 - 当然是另一个名称的长度 - 在 §3.1 中揭示了字符串是字符列表,因此可以说它可以用产生的列表理解来回答等长的字符串!
      • 关于 1.2.1,我承认我很懒惰,没有从出现的许多三元和四元整数乘法中完全计算组合爆炸的结果。
      • 我认为他的意思是 2015 年问世的“用 Haskell 进行功能思考”。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多