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

Haskell自定义BigNumber实现两数相加出现类型错误如何解决?

报错原因
  • zipWith用法错误:Haskell 中函数调用优先级高于运算符,你写的 zipWith + ... 会被编译器解析为尝试对 zipWith 函数本身做加法运算,完全不符合 zipWith 的参数要求。zipWith 的第一个参数是要逐位应用的二元函数,加法作为参数需要包裹在括号中,正确写法为 zipWith (+)。
  • map 参数顺序错误:map 第一个参数是要作用到列表每个元素的函数,第二个才是待遍历的列表。你写的 map (read a) 相当于直接对整个 [String] 类型的 a 调用 read,本身就是类型错误,正确写法为 map read a,将 read 作用到 a 的每个字符串元素上转换为整数。
  • 类型匹配缺失:即使修正前两个问题,逐位相加得到的是 [Int] 类型,而函数要求返回 BigNumber 也就是 [String],还需要将计算后的整数转回字符串;此外当前逻辑没有处理进位,也没有考虑两个输入列表长度不同的情况,不符合大数加法的实际需求。
代码修复

最简可运行版本(仅解决编译报错,未处理进位和长度差异)

somaBN :: BigNumber -> BigNumber -> BigNumber
somaBN a b = map show $ zipWith (+) (map read a) (map read b)

完整大数加法版本(处理进位、长度差异)

somaBN :: BigNumber -> BigNumber -> BigNumber
somaBN a b = reverse $ map show $ addWithCarry 0 reversedA reversedB
  where
    -- 转成整数列表后反转,从最低位开始计算
    reversedA = reverse $ map read a :: [Int]
    reversedB = reverse $ map read b :: [Int]
    -- 带进位的加法逻辑
    addWithCarry carry [] [] = if carry == 0 then [] else [carry]
    addWithCarry carry xs [] = addWithCarry carry xs [0]
    addWithCarry carry [] ys = addWithCarry carry [0] ys
    addWithCarry carry (x:xs) (y:ys) = 
        let total = x + y + carry
            newCarry = total `div` 10
            currentDigit = total `mod` 10
        in currentDigit : addWithCarry newCarry xs ys

该版本实现了标准大数加法逻辑:先反转列表从最低位开始计算,长度不一致时自动补0,计算过程中维护进位,所有位计算完成后仍有进位则额外补最高位,最后将结果反转回高位在前的常规大数表示格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:45:04