Haskell和懒惰的评价

时间:2016-01-13 16:58:24

标签: haskell lazy-evaluation

由于他的懒惰,Haskell可以评估下一个表达式吗?

    take 3 (reverse [1..])

如果是这样,你能试着解释一下我怎么样? 提前致谢

2 个答案:

答案 0 :(得分:4)

答案是没有 - Haskell将无法对此进行评估(在我的系统上它将消耗大量内存并在某些时候崩溃;)

原因是你无法反转无限列表。要看到这一点 - 假设reverse定义为:

reverse [] = []
reverse (x:xs) = reverse xs ++ [x]

你现在要评估

reverse [1..]
= reverse 1:[2..]
{ 2nd case }
= reverse [2..] ++ [1]
= reverse (2:[3..]) ++ [1]
{ 2nd case }
= reverse [3..] ++ [2] ++ [1]
= ...

所以你总会看到另一个reverse [n..]增加n,但绝不会reverse []

所以评估永远不会结束 - 因此你永远无法分辨第一个(或第二个或第三个)元素是什么

有趣的事实

Haskell评估

没有问题
take 0 (reverse [1..])

虽然 - 这次懒惰赢得了一天 - 你能明白为什么吗?

答案 1 :(得分:0)

不,这将会永远运行,但是可能编写一个反向函数,可以懒惰地生成列表的 spines ,因此给出了

reverse' [1..] = repeat undefined
               = undefined : undefined : undefined : ...

而不是实际实现给出的,

reverse [1..] = undefined

具体地

-- Take two lists and return the second with its
-- length fixed (perhaps truncated) to that of the
-- first. Blows up (eventually) if the second list
-- is shorter.
withLengthOf :: [a] -> [b] -> [b]
withLengthOf [] _ = []
withLengthOf (_ : xs) ~(y : ys) =
   y : withLengthOf xs ys

reverse' :: [a] -> [a]
reverse' xs = withLengthOf xs (reverse xs)

这通常不是最有用的东西(因为列表有非常无聊的刺)并且效率有点低。这就是为什么真正的reverse不会打扰。