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

Haskell中scanl处理Either列表的两种案例对比及报错咨询

问题原因:scanl的函数参数顺序搞反了

首先明确scanl的类型定义和参数逻辑:

scanl :: (b -> a -> b) -> b -> [a] -> [b]

它的第一个参数是累加器更新函数,这个函数的参数顺序是先传累加器(类型b),再传当前列表元素(类型a),最终返回新的累加器(类型b)。

第一个案例能运行的原因

你的第一个案例代码:

scanl (\x acc -> x ++ acc) [] [[(Right 1)], [(Right 2)]]

虽然你把lambda的参数顺序写反了(x是累加器,acc是列表元素),但刚好累加器和列表元素的类型完全一致:

  • 初始值[]的类型是[Either a b](累加器类型b)
  • 输入列表的每个元素是[Either a b](元素类型a)
  • x ++ acc操作中,两者都是同类型的列表,类型匹配,因此能正常计算出结果。

第二个案例报错的原因

你的第二个案例代码:

scanl (\x acc -> [x] ++ acc) [] [(Right 1), (Right 2)]

参数顺序错误直接触发类型不匹配:

  • 初始值[]被推导为累加器类型b,根据lambda里的[x] ++ acc,[x]是[b]类型,所以acc必须也是[b]类型才能执行++操作
  • 但输入列表的元素是Either a0 b0类型(元素类型a),lambda里把acc当成了这个元素,导致Either类型和[b]类型无法匹配,编译器因此抛出类型错误。

修正方案

把lambda的参数顺序反过来,遵循先累加器、再列表元素的规则:

scanl (\acc x -> [x] ++ acc) [] [(Right 1), (Right 2)]

运行后会得到正确结果:

[[],[Right 1],[Right 2,Right 1]]

(注:如果想让元素按输入顺序累加,可将[x] ++ acc改为acc ++ [x])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 03:56:04