I'm looking for a non-recursive implementation of sum of digits (a "cross sum") of a non-negative number like this:
cs :: Int -> Int
cs n = sum digits_of_n where digits_of_n = [ . | ... ]
A cross sum of a number (e.g. 512) is the sum of its individual digits (e.g. 5 + 1 + 2 = 8)
cs takes a non-negative number "n" as input, then should use list comprehension to split the number to its digits (e.g. 1234 -> [1,2,3,4]), which then gets summed up.
The part where list comprehension is used is the question, I don't know how to implement that.
The "usual", recursive way would be extracting the digits from a number recursively using modulo and division, and then summing them up like this:
cs :: Int -> Int
cs n = if n == 0 then 0 else n `mod` 10 + cs (n `div` 10)
I have however difficulty expressing this without recursion and with list comprehension, does anyone have ideas regarding this?
First let me remark that such digit sums are an almost completely useless thing to compute, and there are way too many questions here about them.
...anyway – your question boils down to writing a function Int -> [Int]
that produces the list of digits of a nonnegative number. Well, that can of course be done recursively, it can be done using show
(which is a bit of a hack, but then, anything that requires the decimal digits will be a hack), with an unfold
, or indeed with a list comprehension. In this case, you can't very well terminate on having consumed all digits anymore, but you can still compute the number of digits first, then determine each i-th digit separately:
decimalDigits :: Int -> [Int]
decimalDigits n = [ _ | i <- [0 .. ceiling . logBase 10 $ fromIntegral n ]
Then, to compute the i
-th digit, you'll need to use mod
and div
much as you would in the recursive solution, just not with 10 but its i
-th power.