camrymps
camrymps

Reputation: 327

List of integers to single integer - Haskell

I seem to be struggling with something that should be extremely simple in Haskell, but I just cannot figure it out and I need some help. I am trying to convert a list of integers ([3,2,1]) and convert it to a single integer (321).

Here is what I have so far:

fromDigits :: [Integer] -> Integer
fromDigits [] = 0;
fromDigits (x:xs) = x : fromDigits (xs)

What am I doing wrong?

Upvotes: 1

Views: 4061

Answers (2)

leftaroundabout
leftaroundabout

Reputation: 120751

This is not a conversion. The list [3,2,1] may “look” like the number 321, but it's not a one-to-one relation (as Greg alluded – [32,1] looks like the same number), and most certainly not a canonical one (why would you use base 10? Is this actually hexadecimal?) Hence there is really no reason why this should be particularly simple in Haskell1. This is not JavaScript, fortunately.

Repeat of message... it looks like the number 321, and that's all, it's not related to the number in really any meaningful way. So, if you really need to implement this function of questionable worth (I think you shouldn't), then you might as well do the hack to actually exploit the “looks like” thing. I.e.,

fromDigits = read . filter (not . (`elem`"[,]")) . show

This uses the Show instance of lists, to convert the list [3,2,1] into an actual string "[3,2,1]", then throws away the list-related characters, and reads the concatenated string "321" back, yielding the number 321.


1Apart from the fact that it's generally quite simple to implement pure functions in Haskell...

Upvotes: 3

Sibi
Sibi

Reputation: 48766

You can use the worker wrapper approach to do this:

fromDigits :: [Integer] -> Integer
fromDigits xs = aux xs 0
    where aux [] acc = acc
          aux (x:xs) acc  = aux xs ((acc * 10) + x)

Demo:

λ> fromDigits [3,2,1]
321

Or even you can use the higher order function foldl:

λ> foldl' (\acc x -> (acc * 10) + x) 0 [1,2,3]
123

Upvotes: 5

Related Questions