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

Haskell中WarningAccumulator的Applicative实现报错及修复咨询

错误原因与修复

错误原因

你在实现Applicative的<*>方法时,模式匹配的变量绑定顺序完全搞反了:

  • 对于WarningAccumulator w (a -> b)类型的值,构造器内部第一个元素是函数a -> b,第二个元素是警告列表[w]
  • 但你写的模式是(WarningAccumulator (empty, f)),这导致f被绑定到了警告列表[w],而非预期的函数
  • 当你尝试执行f value时,f实际是列表类型[w],根本不是可调用的函数,因此编译器报错“类型[w]没有参数”

另外原实现还忽略了WarningAccumulator的核心语义——应该累积警告,而非只保留单侧的警告列表。

修复后的代码

newtype WarningAccumulator w a = WarningAccumulator (a,[w])
   deriving (Show,Eq)

instance Functor (WarningAccumulator w) where
   fmap :: (a -> b) -> WarningAccumulator w a -> WarningAccumulator w b
   fmap f (WarningAccumulator (value, list)) = WarningAccumulator(f value, list)

instance Applicative (WarningAccumulator w) where
   pure :: a -> WarningAccumulator w a
   pure a = WarningAccumulator (a,[])
   (<*>) :: WarningAccumulator w (a -> b) -> WarningAccumulator w a -> WarningAccumulator w b
   (<*>) (WarningAccumulator (f, warningsF)) (WarningAccumulator (value, warningsV)) = 
      WarningAccumulator (f value, warningsF ++ warningsV)

关键修复点

  1. 修正<*>模式匹配的变量顺序,让f正确绑定到函数a -> b
  2. 用++合并左右两边的警告列表,实现“累积警告”的设计意图

测试示例

-- 带警告的函数
addOne :: WarningAccumulator String (Int -> Int)
addOne = WarningAccumulator (\x -> x+1, ["Adding one"])

-- 带警告的数值
num :: WarningAccumulator String Int
num = WarningAccumulator (5, ["Got number 5"])

-- 应用后得到合并警告的结果
result = addOne <*> num
-- 输出:WarningAccumulator (6,["Adding one","Got number 5"])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 05:40:25