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

Haskell中foldr与foldr1的核心差异咨询

foldr vs foldr1:Haskell折叠操作的核心差异

嘿,完全懂你这种深入研究折叠时突然卡壳的感觉——我当初刚学Haskell时也在这俩家伙身上踩过坑,核心差异其实就俩关键点,给你捋明白:

1. 对空列表的兼容性

这是最直接的区别:

  • foldr 完全支持空列表,因为它需要你传入一个初始值(也就是累加器的起点)。比如:
    foldr (+) 0 []  -- 返回 0,完美运行
    foldr (++) "" []  -- 返回 "",没问题
    
  • foldr1 则完全不能处理空列表,它默认列表至少有一个元素,会用列表的第一个元素作为初始值。如果传空列表,直接触发运行时错误:
    foldr1 (+) []  -- 报错:Prelude.foldr1: empty list
    

2. 初始值的来源

这是本质差异:

  • foldr 的初始值是你显式指定的,它的签名是 foldr :: (a -> b -> b) -> b -> [a] -> b——第二个参数就是初始值,类型可以和列表元素类型不同(比如上面用""和[String]折叠)。
  • foldr1 没有初始值参数,它的签名是 foldr1 :: (a -> a -> a) -> [a] -> a——它必须用列表的第一个元素当初始值,所以折叠操作的输入输出类型必须和列表元素类型一致,而且列表不能为空。

举个更直观的例子对比:

-- foldr:用10当初始值,累加所有元素
foldr (+) 10 [1,2,3]  -- 计算过程:1 + (2 + (3 + 10)) = 16

-- foldr1:用第一个元素1当初始值,累加剩下的元素
foldr1 (+) [1,2,3]  -- 计算过程:1 + (2 + 3) = 6

什么时候用哪个?

  • 如果你不能保证列表非空(比如用户输入、过滤后的结果),必须用foldr,不然程序会炸。
  • 如果你确定列表绝对有至少一个元素(比如已经做过非空检查、生成的列表必然非空),用foldr1更简洁,不用多写一个冗余的初始值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:29:16