无法解决简单的haskell递归问题

无法解决简单的haskell递归问题,haskell,recursion,functional-programming,Haskell,Recursion,Functional Programming,我正在尝试编写一个简单的haskell程序,对一个整数的位数求和,例如,我的整数是888,所以求和应该是8+8+8=24。我记下了这个部分,但我希望我的程序继续运行,直到没有任何东西可以添加。例如,在添加8+8+8=24之后,它应该添加2+4=6,然后返回6。谢谢你的帮助 import System.IO import Data.List integer = 888 todigits :: Integral x => x -> [x] todigits 0 = [] todigi

我正在尝试编写一个简单的haskell程序,对一个整数的位数求和,例如,我的整数是888,所以求和应该是8+8+8=24。我记下了这个部分,但我希望我的程序继续运行,直到没有任何东西可以添加。例如,在添加8+8+8=24之后,它应该添加2+4=6,然后返回6。谢谢你的帮助

import System.IO
import Data.List

integer = 888

todigits :: Integral x => x -> [x]
todigits 0 = []
todigits x = todigits (x `div` 10) ++ [x `mod` 10]

add::[Int]->Int
add (x:xs) = sum(x:xs)

added = add (todigits integer)

main = do
    print(added)

你的函数只需要一次迭代就可以了。您只需要递归调用它,直到得到一个1位数的结果(当然,也可以是一个空列表)

我们将从您现有的函数开始,我已经重命名并重写了该函数,以便它以相反的顺序返回列表(首先是单位数字)。这一点都没有必要,您可以完全使用您以前的定义(因为到目前为止,我们唯一感兴趣的是列表的总和,顺序无关紧要),但如果您需要从数字列表重建数字,这将更加方便(我认为执行得更好一些):

下面是递归的
toDigit
函数:

toDigit :: Integral x => x -> [x]
toDigit x
    | length firstResult < 2 = firstResult
    | otherwise = toDigit . sum $ firstResult
    where firstResult = todigitsOnce x
toDigit::Integral x=>x->[x]
toDigit x
|长度firstResult<2=firstResult
|否则=toDigit。sum$firstResult
其中firstResult=todigitsOnce x

在备选答案中,特别是因为您正在进行递归数字(以10为基数)求和,而默认的
show
实例是以10为基数,所以您可以通过字符串进行往返,并使用视图模式很好地编写

{-# LANGUAGE ViewPatterns #-}

digitSum :: Int -> Int
digitSum x@(show -> (_:"")) = x
digitSum (show -> cs) = digitSum $ sum . map ( read . (:[]) ) $ cs

如果字符串表示为任何单个字符(即
0一个正数,其数字和总是模9全等。此外,由于所有非零数都至少有一个正数,没有负数,因此无法从正数中获得0的数字和。因此:

digitSum x = case (x, x `mod` 9) of
    (0, _) -> 0
    (_, 0) -> 9
    (_, v) -> v
在ghci中试用:

> digitSum 888
6

这个函数可能不会像你期望的那样处理负数——但是,原来的函数也不能很好地处理负数,所以…=)

谢谢你的帮助!我现在明白多了。但是代码编译时还有另一个问题,但是当我运行它时,程序挂起,没有任何输出。不幸的是,我现在无法调试它,听起来好像有一个无限递归在进行。当我想出解决办法时会告诉你的。(也很乐意接受画廊的建议:)(好的,通过手工操作,我已经弄明白了为什么它是无限循环的。我忘了在
firstResult
中我也需要一个非重复性案例!将立即编辑以添加此项。(事实上,在这样做的过程中,我意识到有更大的问题。再次道歉,让我完全重写这个…)对,对此表示歉意,结果证明我的主要错误只是在进行递归调用之前忘记了对列表求和。我有点不好意思,请试试新版本,如果有什么问题请告诉我。
digitSum x = case (x, x `mod` 9) of
    (0, _) -> 0
    (_, 0) -> 9
    (_, v) -> v
> digitSum 888
6