Haskell自定义BigNumber类型实现求和函数somaBN报错如何修复?
问题原因分析
你的报错本质是类型不匹配:
scanner函数接收的参数是String类型,而你zipWith (+)计算得到的是数值列表,编译器推导类型时尝试把结果匹配为scanner要求的[Char]结构,但Char不属于数值类型Num,因此抛出没有Num Char实例的错误- 直接将相加后的数值列表传给
scanner完全不符合函数的输入要求
临时修复方案(仅支持等长无进位的加法,满足你给出的示例效果)
你不需要调用scanner,直接把逐位相加后的结果转成单字符字符串即可:
somaBN :: BigNumber -> BigNumber -> BigNumber somaBN a b = map show $ zipWith (+) (map (read :: String -> Int) a) (map (read :: String -> Int) b)
测试效果:
somaBN ["1","2","3"] ["1","2","3"]
输出为 ["2","4","6"],符合你的预期
完整修复方案(支持不等长、进位的正常大数加法)
上面的版本没有处理长度不一致、进位的问题,符合生产要求的实现如下:
somaBN :: BigNumber -> BigNumber -> BigNumber somaBN a b = reverse $ map show $ addDigits reversedA reversedB 0 where -- 倒序后从最低位开始计算 reversedA = reverse $ map (read :: String -> Int) a reversedB = reverse $ map (read :: String -> Int) b addDigits [] [] carry | carry > 0 = [carry] | otherwise = [] addDigits xs [] carry = addDigits xs [0] carry addDigits [] ys carry = addDigits [0] ys carry addDigits (x:xs) (y:ys) carry = let sumVal = x + y + carry newCarry = sumVal `div` 10 currentDigit = sumVal `mod` 10 in currentDigit : addDigits xs ys newCarry
测试用例:
- 99 + 2 = 101:
somaBN ["9","9"] ["2"]输出["1","0","1"] - 123 + 45 = 168:
somaBN ["1","2","3"] ["4","5"]输出["1","6","8"]
内容的提问来源于stack exchange,提问作者Francisca Almeida
相关产品推荐
相关产品推荐

