Haskell语义调用的名称/值

问题描述 投票:-1回答:2

我是Haskell的新手,我有一个问题

h x = x : (h x)
g xs = [head xs, head xs - 1]

假设语义是按名称调用和按值调用,运行g(h 2)有什么结果?

haskell semantics
2个回答
0
投票

让我们逐步进行。

首先,h x = x : (h x)是递归的。函数h是根据其自身定义的:给定一些x会将其放在list上,该x : x : x : ...是无限的。换句话说,由于递归从不终止,因此列表不能是有限的。但是它不会永远挂起。为什么?

因为Haskell很懒。它不会对绝对必要的表达式进行评估。在您的情况下,如果调用h 2,则根本不会在内存中创建无限列表。为什么?

因为g仅请求名为xs的给定列表的前两个元素。 Haskell足够聪明,可以只在需要的时间内扩展无限列表,而不会浪费资源。通常,这是懒惰的好处。它也可以与其他表达式一起使用,不仅限于列表。


0
投票

“按名称呼叫”是非记忆非严格评估策略:

h x = x : (h x)
g xs = [head xs, head xs - 1]

g (h 2) = let {xs = (h 2)} in [head xs, head xs - 1]
        = [let {xs = (h 2)} in head xs, let {xs = (h 2)} in head xs - 1]
        = [head (h 2), let {xs = (h 2)} in head xs - 1]
        = [head (let {x = 2} in x : (h x)}), let {xs = (h 2)} in head xs - 1]
        = [let {x = 2} in x, let {xs = (h 2)} in head xs - 1]
        = [2, let {xs = (h 2)} in head xs - 1]
        = ....

“按需拨打电话”是“ [不受限制]”,又称“懒惰”评估策略:h x = x : (h x) g xs = [head xs, head xs - 1] g (h 2) = let {xs = (h 2)} in [head xs, head xs - 1] = let {xs = (2 : (h 2))} in [head xs, head xs - 1] = let {xs = (2 : (h 2))} in [2, head xs - 1] = ....

“按价值致电”是

strict

评估策略:h x = x : (h x) g xs = [head xs, head xs - 1] g (h 2) = let {xs = (h 2)} in [head xs, head xs - 1] = let {xs = (2 : (h 2))} in [head xs, head xs - 1] = let {xs = (2 : (2 : (h 2)))} in [head xs, head xs - 1] = let {xs = (2 : (2 : (2 : (h 2))))} in [head xs, head xs - 1] = ....
以上所有假设都在GHCi提示符下输入g (h 2),因此需要用它完整打印。
© www.soinside.com 2019 - 2024. All rights reserved.