【发布时间】:2016-02-20 03:33:08
【问题描述】:
大多数其他语言都使用按值调用。 Haskell 使用按名称调用(惰性评估),我想知道它是如何运行的,我认为与按值调用相比会更好。
以问题为例,
repeat' 函数定义如下:
repeat' :: a -> [a]
repeat' x = x:repeat' x
使用repeat' 3会得到一个无限的3个列表,ghci> repeat' 3会产生3个连续的,
但take 5 (repeat' 3) 只会得到[3,3,3,3,3]。
haskell 如何知道以第五次递归内部 repeat' 函数结束?此外,我认为这不是take 的问题。
代码在哪个阶段执行与按值调用不同?
谢谢
【问题讨论】:
-
总之,总是减少最外层的表达式,它是可约的:
head (repeat 3)->head (3:repeat 3)->3。在第一种情况下,head是不可约的,因为它必须对其参数进行模式匹配,但它的参数不是构造函数。但是,repeat没有模式匹配,所以总是可以减少它。第一次归约后,head现在可以归约,因为有一个构造函数(:)。 -
"当代码被执行到哪个阶段它与按值调用不同?" erm...什么?您是否在问类似这样的问题:假设我们使用按值调用作为传递函数参数的策略而不是按名称调用,这会有所不同吗?我相信对于按名称调用-值你实际上是指急切减少,在这种情况下
repeat 3只是undefined和take 5 undefined = undefined并且程序将永远卡住。 -
@Bakuriu,您可以将按名称调用视为惰性求值(理解起来会更好)。只要编译器可以,表达式可以进行求值时,将使用按值调用,当然,Haskell 不使用按值调用。我不明白你说 repeat 3 is just undefined 以及它将被评估的点。大多数其他语言(如 c/c++)使用按值调用,我想知道如何Haskell 是否处理
undefined(重复 3)?谢谢