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
代码解释
- 第一个模式匹配
price _ Empty = 0:当列表是空的,不管定价函数是什么,总价都是0,这里用_表示我们不需要用到这个定价函数参数。 - 第二个模式匹配
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
相关产品推荐
相关产品推荐

