Haskell 和惰性评估
Haskell and lazy evaluation
因为他的懒惰,可以Haskell计算下一个表达式吗?
take 3 (reverse [1..])
如果是这样,你能解释一下怎么做吗?
提前致谢
答案是 否 - 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..])
虽然 - 这次懒惰 赢得了胜利 - 你能明白为什么吗?
不,那会 运行 永远,但是 可能 编写一个反向函数来生成列表的 脊柱 懒惰地,因此给出
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
不会打扰。
因为他的懒惰,可以Haskell计算下一个表达式吗?
take 3 (reverse [1..])
如果是这样,你能解释一下怎么做吗? 提前致谢
答案是 否 - 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..])
虽然 - 这次懒惰 赢得了胜利 - 你能明白为什么吗?
不,那会 运行 永远,但是 可能 编写一个反向函数来生成列表的 脊柱 懒惰地,因此给出
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
不会打扰。