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

Haskell中基于foldr实现的squareOn函数原理及lambda表达式中acc含义咨询

嘿,这个问题问得很到位!我来一步步帮你把这个squareOn函数拆明白,先从你好奇的acc说起~

首先,acc是什么类型?

先回忆foldr的标准类型:

foldr :: (b -> c -> c) -> c -> [b] -> c

我们看squareOn里的foldr调用:第二个参数是id——也就是那个“输入什么就返回什么”的恒等函数,它的类型是t -> t。

这里foldr的c类型就被确定为函数类型a -> a(因为最终squareOn的返回值是a -> a,正好对应foldr输出的c)。那lambda里的acc就是foldr传递的累加器,它的类型自然就是a -> a——没错,acc本身就是一个函数!它的作用是“携带我们已经处理完列表右侧部分后得到的判断逻辑”,后面结合例子你会更清楚它的用处。

然后,squareOn的具体工作原理

先把它的类型签名翻译成人话:

squareOn :: (Eq a, Num a) => [a] -> a -> a

它接受一个元素类型为a(要求能比较相等、能做乘法运算)的列表,返回一个函数;这个返回的函数接受一个a类型的值,如果这个值在输入列表里,就返回它的平方,否则返回它本身。

我们拿squareOn [1,2,3]这个具体例子,跟着foldr的执行流程走一遍:

foldr是从列表的右端开始处理的,初始累加器是id(也就是\y -> y,兜底逻辑:啥都不匹配就返回原数):

  1. 处理最后一个元素3:
    把x=3和acc=id代入lambda,得到新函数:

    \y -> if y == 3 then 3*3 else id y
    

    逻辑:输入y是3就返回9,否则返回y本身。

  2. 处理元素2:
    把x=2和acc=上面的函数代入lambda,得到新函数:

    \y -> if y == 2 then 2*2 else (之前的函数) y
    

    逻辑:y是2就返回4,否则交给上一步的函数判断(是不是3,是就9,否则返回y)。

  3. 处理第一个元素1:
    把x=1和acc=上面的函数代入lambda,得到最终的函数:

    \y -> if y == 1 then 1*1 else (之前的函数) y
    

    逻辑:先看y是不是1(是就返回1),不是就看是不是2(是就4),还不是就看是不是3(是就9),都不匹配就返回y本身。

当你调用squareOn [1,2,3] 2时,就会触发这个逻辑返回4;调用squareOn [1,2,3] 4,因为4不在列表里,就返回4本身。

本质上,foldr在这里帮我们把列表里的每个元素拼接成了一个链式判断:每个元素对应“匹配就返回平方,否则交给后续逻辑”的分支,初始的id就是兜底的“都不匹配返回原数”逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 08:33:13