Reputation: 327
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
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
.
Upvotes: 3
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