由于他的懒惰,Haskell可以评估下一个表达式吗?
take 3 (reverse [1..])
如果是这样,你能试着解释一下我怎么样? 提前致谢
答案 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
不会打扰。