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

Haskell代数数据类型问题:计算自定义杂货列表总价

正确实现Haskell杂货列表总价计算函数

先梳理你现有代码的问题:

  • 类型不匹配:你直接把Item构造器(比如A、B)和整数相加,这是错误的——A是Item类型,而你需要的是它对应的价格(Int类型),得用传入的定价函数p把Item转成价格。
  • 递归参数缺失:price函数需要两个参数(定价函数和列表),递归调用时必须把p传递下去,不能只写price xs。
  • 缺少终止条件:没有处理Empty空列表的情况,递归到空列表时应该返回0,作为累加的起点。

正确的递归实现

price :: (Item -> Int) -> List -> Int
-- 空列表总价为0,终止递归
price _ Empty = 0
-- 当前商品价格 + 剩余列表的总价
price p (Add x xs) = p x + price p xs

代码解释

  1. 第一个模式匹配price _ Empty = 0:当列表是空的,不管定价函数是什么,总价都是0,这里用_表示我们不需要用到这个定价函数参数。
  2. 第二个模式匹配price p (Add x xs) = p x + price p xs:
    • 取出列表的第一个商品x,用p x获取它的价格;
    • 递归调用price p xs计算剩余列表的总价;
    • 把两者相加,得到当前整个列表的总价。

测试验证

用你定义的list1和p函数测试:

-- 计算结果应为2 + 4 = 6
price p list1

进阶写法(用折叠函数)

如果想更简洁,可以基于折叠(fold)来实现。首先给自定义的List实现折叠逻辑:

-- 自定义List的foldr实现
foldrList :: (Item -> a -> a) -> a -> List -> a
foldrList _ acc Empty = acc
foldrList f acc (Add x xs) = f x (foldrList f acc xs)

-- 基于foldrList实现price
price :: (Item -> Int) -> List -> Int
price p = foldrList (\item total -> p item + total) 0

这种写法更贴合函数式编程的风格,把列表遍历和累加的逻辑分离了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 05:25:21