gpt4 book ai didi

haskell - 为什么这个 Haskell 语句不懒惰地评估?

转载 作者:行者123 更新时间:2023-12-04 05:34:51 25 4
gpt4 key购买 nike

我定义了以下函数:

ex 1 x = 1
ex 0 x = 0
ex b x = b ** x

然后,当我执行以下操作时:
1 `ex` (sum [1..])

它试图计算无限序列的总和,而不是懒惰并返回 1。为什么?

编辑:经过进一步调查,我发现如果我定义 ex,就会发生懒惰。文件中的函数,但如果我在 GHCI 中定义它则不是:
$ ghci
GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
Loading package base ... linking ... done.
Prelude> let ex 1 x = 1
Prelude> let ex b x = b ** x
Prelude> ex 1 (sum [1..])
<interactive>: out of memory (requested 1048576 bytes)

如果我拉 ex定义到文件中(在本例中为 test.hs):
$ ghci
GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
Loading package base ... linking ... done.
Prelude> :load test.hs
[1 of 1] Compiling Main ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> ex 1 (sum [1..])
1.0

那么,新的问题是为什么?

最佳答案

在 GHCi 中,每个 let语句引入了 ex 的新定义,而不是您期望的多个模式案例。所以它挂起,因为当你输入 ex 1 (sum [1..])之后,只有最后的ex b x = b ** x版本存在。

如果你想在 GHCi 中定义一个具有多个模式案例的函数,你需要把它放在一个 let 中。声明,像这样:

let ex 1 x = 1; ex 0 x = 0; ex b x = b ** x

这同样适用于通常跨多行编写的任何其他内容,例如 do符号。例如,像这样的函数:
f x = do
y <- get
put (x + y)
return y

在 GHCi 中必须这样写:
let f x = do { y <- get; put (x + y); return y }

关于haskell - 为什么这个 Haskell 语句不懒惰地评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3206410/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com