gpt4 book ai didi

haskell - Haskell如何进行后期评估?

转载 作者:行者123 更新时间:2023-12-02 16:08:09 27 4
gpt4 key购买 nike

我听说 Haskell 评估较晚。然而,无论我尝试做什么,它的评估方式似乎都与任何其他编程语言相同;

考虑以下代码:

test :: Bool -> IO()
test n = do
let y = 5
print n

main = do
let y = 8
test (y == 8)

此代码输出:

True
  • 为什么这段代码提前评估“y”?
  • 能给我一个 Haskell 中的延迟评估示例吗?

最佳答案

首先要记住一些重要的一般信息:

Haskell 变量是不可变的
总是,无一异常(exception),而且你对此无能为力。

因此,当您编写类似 let y = 5 的内容时,它永远不会更改某些已存在变量的值。相反,它引入了一个名为 y 的新变量并为其提供所需的值。无论程序中的其他位置是否也有一个名为 y 的变量,都无关紧要,这完全是一个不同变量。事实上,考虑一下:

main :: IO ()
main = do
let y = 1
do let y = 2
print y
print y

输出为

2
1

在您的示例中,let y = 5 语句根本没有任何效果,很可能会被编译器完全丢弃。事实上,如果您使用 -Wall 进行编译(正如您应该的那样),GHC 会告诉您:

/tmp/wtmpf-file30239.hs:4:7: warning: [-Wunused-local-binds]
Defined but not used: ‘y’
|
4 | let y = 5
| ^

因此,特别是,y == 8 检查不可能受到您可以使用的任何 let y = 语句的影响。

事实上,更一般地说,惰性求值不会影响值。这是拥有纯函数式语言的伟大之处之一:因为一切都是恒定的,惰性求值通常不会影响值语义,它只会影响完成相同工作的顺序 - 这可以 影响某件事终止的速度(或者是否终止),但不影响它完成时产生的值。 y == 8 在运行时进入 test 函数之前还是之后进行计算并不重要,事实上 Haskell 标准并没有告诉任何相关信息 –它告诉我们的是,如果 test 最终甚至没有使用参数值,那么非终止参数不应阻止 test 终止(非严格语义)。因此,以下演示了惰性求值的实际应用:

unobtanium :: Bool
unobtanium = unobtanium -- infinite loop

don'tTest :: Bool -> IO ()
don'tTest a = do
putStrLn "Meh, I'm too lazy to do it."

main :: IO ()
main = do
let y = unobtanium
don'tTest y

...即使 y 不可能被评估。

关于haskell - Haskell如何进行后期评估?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59131342/

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