为什么`take`返回大数[],即使列表是无限的?

cha*_*ni2 2 haskell lazy-evaluation

我怀疑为什么Haskell无法处理以下行

Prelude> take 1000000000000 $ repeat ' '
Run Code Online (Sandbox Code Playgroud)

该行代码将返回:

""
Run Code Online (Sandbox Code Playgroud)

这显然不是1,000,000,000,000个空间.

如果我尝试少于零,它会打印很长时间.

最困扰我的是,如果我只是写作

Prelude> repeat ' '
Run Code Online (Sandbox Code Playgroud)

它会工作,即使是一个很大多个零的.

那么,为什么Haskell不能像repeat单独使用那样打印很长时间?

Tik*_*vis 11

你是32位系统吗?我怀疑1000000000000包裹Int成负数.它等于约2^40.

您可以通过输入检查发生了什么1000000000000 :: Int.

take 使用负数只返回空列表:

Prelude> take (- 1) [1,2,3]
[]
Run Code Online (Sandbox Code Playgroud)

作为参考,take只需要Int:

Prelude> :t take
take :: Int -> [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

  • 确切地说,`1000000000000 :: Int32`的计算结果为`-727379968`.另请参阅:[`genericTake`](http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-List.html#v:genericTake). (4认同)