【问题标题】:Why is [1..n] not handled the same way as [n..1] in Haskell?为什么 [1..n] 的处理方式与 Haskell 中的 [n..1] 不同?
【发布时间】:2011-09-08 13:54:41
【问题描述】:

我试图解决一个在被函数映射后需要列表最大值的问题。该列表是从 a 到 b 的范围,其中 a>b 或 b>a。因为 Haskell 还可以定义递减列表,所以我认为我不需要检查 a>b 是否也不需要将边界翻转到 b..a。该函数看起来有点像这样:

f a b = maximum . map aFunction $ [a..b]

但是如果列表在减少,即 a>b,那么 Haskell 会给我一个例外:

Prelude.maximum: empty list

因此,由于某种原因,递减列表将空列表交给了最大值函数。这是为什么呢?

我知道maximum 是根据foldl1 max 定义的,而foldl1 需要一个非空列表,但我不知道为什么像[10..1] 这样的列表在交给foldl1 时是空的.

【问题讨论】:

标签: list haskell


【解决方案1】:

[a..b] 脱糖到enumFromTo a b。对于标准数字类型(模数几个浮动的怪癖),这会不断添加一个,直到您成为>= b。所以b < a这里是空的。

您可以使用以下语法[a,a'..b] 更改增量,然后以a'-a 为增量执行步骤。所以[10,9..1] 就是你想要的。

【讨论】:

  • 谢谢你真的做到了。我完全忘记了踩踏。
【解决方案2】:

这是因为Haskell Report Arithmetic Sequences 中定义序列的方式:

[ e1..e3 ] = enumFromTo e1 e3

Haskell Report The Enum Class

序列 enumFromTo e1 e3 是列表 [e1,e1 + 1,e1 + 2, ... e3]。 如果 e1 > e3,则列表为空。

(强调)。

【讨论】:

    【解决方案3】:

    它们的处理方式完全相同。您从第一个界限开始并数数。

    【讨论】:

      猜你喜欢
      • 2022-09-26
      • 2011-02-16
      • 2013-06-10
      • 2020-10-19
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 2014-02-06
      • 1970-01-01
      相关资源
      最近更新 更多