You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Haskell中take' 5 (repeat' 3)不会无限执行?

为什么take' 5 (repeat' 3)不会无限执行?

先看我们定义的两个函数:

take' :: (Num i, Ord i) => i -> [a] -> [a]
take' n _
    | n <= 0 = []
take' _ [] = []
take' n (x:xs) = x : take' (n-1) xs

repeat' :: a -> [a]
repeat' x = x:repeat' x

核心原因就是Haskell的惰性求值——按需计算,只有当值被实际用到时才会触发计算,而take'的逻辑刚好控制了需要计算的量:

  1. 先看repeat' 3:它的定义是3 : repeat' 3,但这个表达式不会立刻递归到底。它更像一个"待兑现的承诺":

    • 当你需要列表的第一个元素时,它给你3;
    • 当你需要列表剩下的部分(也就是xs)时,它才会去计算下一个repeat' 3。
  2. 再看take'的执行流程:

    • 调用take' 5 (repeat' 3),此时n=5>0,列表不是空的,匹配第三个模式,得到3 : take' 4 (repeat' 3)——这里只需要repeat' 3的第一个元素3,剩下的repeat' 3暂时不用管;
    • 接下来计算take' 4 (repeat' 3),同样只取repeat' 3的第一个元素3,得到3 : take' 3 (repeat' 3);
    • 重复这个过程,直到n=1时,得到3 : take' 0 (repeat' 3);
    • 当调用take' 0 (repeat' 3)时,匹配第一个模式,直接返回[],完全不需要再去处理repeat' 3的部分。

整个过程里,repeat'从来没有被完整执行过——它只生成了take'需要的5个3,当take'的n减到0后,不再需要更多元素,repeat'的递归自然就不会继续触发了。

内容的提问来源于stack exchange,提问作者SK7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 01:55:18