this is the question:
"Write a function that computes the
mean of a list, i.e. the sum of all
elements in the list divided by its
length. (You may need to use the
fromIntegral function to convert the
length of the list from an integer
into a floating point number.)"
first i tried this:
mean :: [Double] -> Double
mean [] = 0
mean (x:xs) = (x + mean xs) / (1 + mean xs)
but it give me strange results, for example, when i use it like that:
mean [2,4,6]
it give me the result: 1.41176
where it should be: 4
why?
i tried another thing:
mean :: [Double] -> Double
mean list = (summ list) / (count list)
where count [] = 0
count (x:xs) = 1 + count xs
summ [] = 0
summ (x:xs) = x + summ xs
but i have an error when i tried to load the file into GHC.
the error is:
parse error on input 'count'
Failed, modules loaded: none
again, what am i doing wrong?
at last, i tried this one (that succeeded):
mean :: [Double] -> Double
count [] = 0
count (x:xs) = 1 + count xs
summ [] = 0
summ (x:xs) = x + summ xs
mean list = summ list / count list
it's the same as the above one (with the 'where' keyword), but it succeed only here, and not in the above one.
why?
thanks a lot.
p.s.
i'm learning from the book -- Real World Haskell
and the exercise is from here -- (roll it down :-))
thanks to you all.
it's a strange thing.
the second example also work for me too when i copied it from here and tested it.
i don't know why it didn't work for me yesterday :-)
but i still don't understand why the first one doesn't work.
i think it should be like that
(2 + mean [4,6]) / (1 + mean [4,6])
(4 + mean [6 ]) / (1 + mean [ 6])
(6 + mean [ ]) / (1 + mean [ ])
so now it is like that
(6 + 0 ) / (1 + 0 ) -- last recursion
(4 + (6 + 0) ) / (1 + (1 + 0) )
(2 + (4 + (6 + 0))) / (1 + (1 + (1 + 0))
so now it should be: 12 / 3
isn't it?
what i don't understand?
thank you :-).
You get the wrong answers for your first attempt, because you use an incorrect formula. Garbage in, garbage out. (Other people have covered this.)
You are probably getting a parse error because some lines are using spaces and others are using tabs. Or you are using all tabs, but with a non-standard tab width.
No indentation is used or required here, so the spaces -v- tabs issue doesn't arise.
Your first attempt evaluates like so:
6 / 1
4 + 6 / 1 + 6
2 + (10/7) / 1 + (10/7)
which isn't what you wanted.
The second attempt is fine.
Correct:
import Data.List (foldl')
mean :: Fractional a => [a] -> a
mean = uncurry (/) . foldl' (\(s, n) x -> (s + x, n + 1)) (0, 0)
mean [2,4,6] = uncurry (/) $ foldl' (...) (0, 0) [2,4,6]
= uncurry (/) $ foldl' (...) (2, 1) [4,6]
= uncurry (/) $ foldl' (...) (6, 2) [6]
= uncurry (/) $ foldl' (...) (12, 3) []
= uncurry (/) (12, 3)
= 12 / 3
= 4
Incorrect:
mean [] = 0
mean (x:xs) = (x + mean xs) / (1 + mean xs)
mean [6] = mean (6 : [])
= (6 + mean []) / (1 + mean [])
= (6 + 0) / (1 + 0)
= 6
mean [4,6] = mean (4 : [6])
= (4 + mean [6]) / (1 + mean [6])
= (4 + 6) / (1 + 6)
= 10/7
mean [2,4,6] = mean (2 : [4,6])
= (2 + mean [4,6]) + (1 + mean [4,6])
= (2 + 10/7) / (1 + 10/7)
= 24/17
Say we define
naivemean l = sum l / fromIntegral (length l)
It has a couple of serious limitations. First, the definition does not cover lists of Int:
*Main> naivemean ([1] :: [Int])
<interactive>:1:0:
No instance for (Fractional Int)
arising from a use of `naivemean' at <interactive>:1:0-21
Possible fix: add an instance declaration for (Fractional Int)
In the expression: naivemean ([1] :: [Int])
In the definition of `it': it = naivemean ([1] :: [Int])
Second, it blows the stack for large lists:
*Main> naivemean [1..1000000]
*** Exception: stack overflow
Also, it makes two passes, one for sum and one for length, over the list when a single pass will do.
We can correct all three problems with
{-# LANGUAGE BangPatterns #-}
mean :: (Real a, Fractional b) => [a] -> b
mean = go (toRational 0) 0
where
go !s !l [] = fromRational s / fromIntegral l
go s l (x:xs) = go (s+.x) (l+1) xs
s +. x = s + toRational x
Bang patterns force strict evaluation of the marked parameters. Without the bangs, the code above will also blow the stack when given a long list, but for a different reason: lazy evaluation of l for example generates a long unevaluated chain of the form
0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + ...
In this case, lazy evaluation is creating more work in the form of allocating all the suspended computations than it would be to simply increment the counter on every iteration.
As a beginner, fromRational and toRational are probably confusing too. Consider the type of the division function:
*Main> :t (/)
(/) :: (Fractional a) => a -> a -> a
That means division is defined for any two values of the same type that is an instance of Fractional. Int is not one of those types:
*Main> (1::Int) / (2::Int)
<interactive>:1:0:
No instance for (Fractional Int)
arising from a use of `/' at <interactive>:1:0-18
Possible fix: add an instance declaration for (Fractional Int)
In the expression: (1 :: Int) / (2 :: Int)
In the definition of `it': it = (1 :: Int) / (2 :: Int)
One definition of mean ought to cover all of [Int], [Float], and [Double] but without the rational bits (and without the type annotation), the type inferred for mean is
*Main> :t mean
mean :: [Double] -> Double
because of the division by the length of the list.
It turns out that Int, Float, and Double are instances of the typeclass Real,and any Real may be converted to Rational
*Main> :t toRational
toRational :: (Real a) => a -> Rational
and Rational may be converted to Fractional:
*Main> :t fromRational
fromRational :: (Fractional a) => Rational -> a
Finally, for large lists, there's also a chance that we could overflow a machine double, but Rational gives us arbitrary precision.
If you have a background in languages such as C or Java that promote types automatically to handle these cases, you'll find this particular inflexibility of Haskell's type system to be confusing and frustrating. I'm afraid you just have to learn to deal with it.
Having done all that, we can now
*Main> mean ([1..1000000] :: [Int])
500000.5
or
*Main> mean ([1..1000000] :: [Double])
500000.5
Warning: untested code ahead. In your definition of mean, you need to accurately carry along both the running sum and the running length, and as others have pointed out, you're not doing that. Something like the following should work:
mean0 sum len [] = sum / len
mean0 sum len (x:xs) = mean0 (sum+x) (len+1) xs
This definition passes along two accumulators, one each for the running total and the running count, that are updated as you recurse along the list. When the function finally runs out of list to process (the base case) it just does the needed calculation.
To use mean0, you just write
mean0 0 0 [2, 4, 6]
As you can see, it's sort of annoying to provide the initial values for the accumulators, so it's common to provide a wrapper like
mean xs = mean0 0 0 xs
Now, you write mean [2, 4, 6] just like you wanted to.
Haskell: The most beautiful imperative language
import Control.Monad.ST
import Data.STRef
import Control.Monad
mean xs = s / l
where (s,l) = runST $ do{
acc <- newSTRef (0,0);
forM_ xs $ \x -> do{
modifySTRef acc $ \(a,b) -> (x+a,1+b)
};
readSTRef acc }
let mean x = sum (x) / fromIntegral(length(x))
mean [2.0, 4.0, 6.0]
Of course, this must be improved (empty list, does work for doubles...).
Related
Given an arbitrary number, how can I process each digit of the number individually?
Edit
I've added a basic example of the kind of thing Foo might do.
For example, in C# I might do something like this:
static void Main(string[] args)
{
int number = 1234567890;
string numberAsString = number.ToString();
foreach(char x in numberAsString)
{
string y = x.ToString();
int z = int.Parse(y);
Foo(z);
}
}
void Foo(int n)
{
Console.WriteLine(n*n);
}
Have you heard of div and mod?
You'll probably want to reverse the list of numbers if you want to treat the most significant digit first. Converting the number into a string is an impaired way of doing things.
135 `div` 10 = 13
135 `mod` 10 = 5
Generalize into a function:
digs :: Integral x => x -> [x]
digs 0 = []
digs x = digs (x `div` 10) ++ [x `mod` 10]
Or in reverse:
digs :: Integral x => x -> [x]
digs 0 = []
digs x = x `mod` 10 : digs (x `div` 10)
This treats 0 as having no digits. A simple wrapper function can deal with that special case if you want to.
Note that this solution does not work for negative numbers (the input x must be integral, i.e. a whole number).
digits :: Integer -> [Int]
digits = map (read . (:[])) . show
or you can return it into []:
digits :: Integer -> [Int]
digits = map (read . return) . show
or, with Data.Char.digitToInt:
digits :: Integer -> [Int]
digits = map digitToInt . show
the same as Daniel's really, but point free and uses Int, because a digit shouldn't really exceed maxBound :: Int.
Using the same technique used in your post, you can do:
digits :: Integer -> [Int]
digits n = map (\x -> read [x] :: Int) (show n)
See it in action:
Prelude> digits 123
[1,2,3]
Does that help?
You could also just reuse digits from Hackage.
Textbook unfold
import qualified Data.List as L
digits = reverse . L.unfoldr (\x -> if x == 0 then Nothing else Just (mod x 10, div x 10))
You can use
digits = map (`mod` 10) . reverse . takeWhile (> 0) . iterate (`div` 10)
or for reverse order
rev_digits = map (`mod` 10) . takeWhile (> 0) . iterate (`div` 10)
The iterate part generates an infinite list dividing the argument in every step by 10, so 12345 becomes [12345,1234,123,12,1,0,0..]. The takeWhile part takes only the interesting non-null part of the list. Then we reverse (if we want to) and take the last digit of each number of the list.
I used point-free style here, so you can imagine an invisible argument n on both sides of the "equation". However, if you want to write it that way, you have to substitute the top level . by $:
digits n = map(`mod` 10) $ reverse $ takeWhile (> 0) $ iterate (`div`10) n
Via list comprehension:
import Data.Char
digits :: Integer -> [Integer]
digits n = [toInteger (digitToInt x) | x <- show n]
output:
> digits 1234567890
[1,2,3,4,5,6,7,8,9,0]
I was lazy to write my custom function so I googled it and tbh I was surprised that none of the answers on this website provided a really good solution – high performance and type safe. So here it is, maybe somebody would like to use it. Basically:
It is type safe - it returns a type checked non-empty list of Word8 digits (all the above solutions return a list of numbers, but it cannot happen that we get [] right?)
This one is performance optimized with tail call optimization, fast concatenation and no need to do any reversing of the final values.
It uses special assignment syntax which in connection to -XStrict allows Haskell to fully do strictness analysis and optimize the inner loop.
Enjoy:
{-# LANGUAGE Strict #-}
digits :: Integral a => a -> NonEmpty Word8
digits = go [] where
go s x = loop (head :| s) tail where
head = fromIntegral (x `mod` 10)
tail = x `div` 10
loop s#(r :| rs) = \case
0 -> s
x -> go (r : rs) x
Here's an improvement on an answer above. This avoids the extra 0 at the beginning ( Examples: [0,1,0] for 10, [0,1] for 1 ). Use pattern matching to handle cases where x < 10 differently:
toDigits :: Integer -> [Integer] -- 12 -> [1,2], 0 -> [0], 10 -> [1,0]
toDigits x
| x < 10 = [x]
| otherwise = toDigits (div x 10) ++ [mod x 10]
I would have put this in a reply to that answer, but I don't have the needed reputation points :(
Applicative. Pointfree. Origami. Neat.
Enjoy:
import Data.List
import Data.Tuple
import Data.Bool
import Control.Applicative
digits = unfoldr $ liftA2 (bool Nothing) (Just . swap . (`divMod` 10)) (> 0)
I've been following next steps(based on this comment):
Convert the integer to a string.
Iterate over the string
character-by-character.
Convert each character back to an integer,
while appending it to the end of a list.
toDigits :: Integer -> [Integer]
toDigits a = [(read([m])::Integer) | m<-show(a)]
main = print(toDigits(1234))
For returning a list of [Integer]
import Data.Char
toDigits :: Integer -> [Integer]
toDigits n = map (\x -> toInteger (digitToInt x)) (show n)
The accepted answer is great but fails in cases of negative numbers since mod (-1) 10 evaluates to 9. If you would like this to handle negative numbers properly... which may not be the case the following code will allow for it.
digs :: Int -> [Int]
digs 0 = []
digs x
| x < 0 = digs ((-1) * x)
| x > 0 = digs (div x 10) ++ [mod x 10]
The accepted answer is correct except that it will output an empty list when input is 0, however I believe the output should be [0] when input is zero.
And I don't think it deal with the case when the input is negative. Below is my implementation, which solves the above two problems.
toDigits :: Integer -> [Integer]
toDigits n
| n >=0 && n < 10 = [n]
| n >= 10 = toDigits (n`div`10) ++ [n`mod`10]
| otherwise = error "make sure your input is greater than 0"
I would like to improve upon the answer of Dave Clarke in this page. It boils down to using div and mod on a number and adding their results to a list, only this time it won't appear reversed, nor resort to ++ (which is slower concatenation).
toDigits :: Integer -> [Integer]
toDigits n
| n <= 0 = []
| otherwise = numToDigits (n `mod` 10) (n `div` 10) []
where
numToDigits a 0 l = (a:l)
numToDigits a b l = numToDigits (b `mod` 10) (b `div` 10) (a:l)
This program was a solution to a problem in the CIS 194 course at UPenn that is available right here. You divide the number to find its result as an integer and the remainder as another. You pass them to a function whose third argument is an empty list. The remainder will be added to the list in case the result of division is 0. The function will be called again in case it's another number. The remainders will add in order until the end.
Note: this is for numbers, which means that zeros to the left won't count, and it will allow you to have their digits for further manipulation.
digits = reverse . unfoldr go
where go = uncurry (*>) . (&&&) (guard . (>0)) (Just . swap . (`quotRem` 10))
I tried to keep using tail recursion
toDigits :: Integer -> [Integer]
toDigits x = reverse $ toDigitsRev x
toDigitsRev :: Integer -> [Integer]
toDigitsRev x
| x <= 0 = []
| otherwise = x `rem` 10 : toDigitsRev (x `quot` 10)
I'm trying to solve the following problem in Haskell: given an integer return the list of its digits. The constraint is I have to only use one of the fold* functions (* = {r,l,1,l1}).
Without such constraint, the code is simple:
list_digits :: Int -> [Int]
list_digits 0 = []
list_digits n = list_digits r ++ [n-10*r]
where
r = div n 10
But how do I use fold* to, essentially grow a list of digits from an empty list?
Thanks in advance.
Is this a homework assignment? It's pretty strange for the assignment to require you to use foldr, because this is a natural use for unfoldr, not foldr. unfoldr :: (b -> Maybe (a, b)) -> b -> [a] builds a list, whereas foldr :: (a -> b -> b) -> b -> [a] -> b consumes a list. An implementation of this function using foldr would be horribly contorted.
listDigits :: Int -> [Int]
listDigits = unfoldr digRem
where digRem x
| x <= 0 = Nothing
| otherwise = Just (x `mod` 10, x `div` 10)
In the language of imperative programming, this is basically a while loop. Each iteration of the loop appends x `mod` 10 to the output list and passes x `div` 10 to the next iteration. In, say, Python, this'd be written as
def list_digits(x):
output = []
while x > 0:
output.append(x % 10)
x = x // 10
return output
But unfoldr allows us to express the loop at a much higher level. unfoldr captures the pattern of "building a list one item at a time" and makes it explicit. You don't have to think through the sequential behaviour of the loop and realise that the list is being built one element at a time, as you do with the Python code; you just have to know what unfoldr does. Granted, programming with folds and unfolds takes a little getting used to, but it's worth it for the greater expressiveness.
If your assignment is marked by machine and it really does require you to type the word foldr into your program text, (you should ask your teacher why they did that and) you can play a sneaky trick with the following "id[]-as-foldr" function:
obfuscatedId = foldr (:) []
listDigits = obfuscatedId . unfoldr digRem
Though unfoldr is probably what the assignment meant, you can write this using foldr if you use foldr as a hylomorphism, that is, building up one list while it tears another down.
digits :: Int -> [Int]
digits n = snd $ foldr go (n, []) places where
places = replicate num_digits ()
num_digits | n > 0 = 1 + floor (logBase 10 $ fromIntegral n)
| otherwise = 0
go () (n, ds) = let (q,r) = n `quotRem` 10 in (q, r : ds)
Effectively, what we're doing here is using foldr as "map-with-state". We know ahead of time
how many digits we need to output (using log10) just not what those digits are, so we use
unit (()) values as stand-ins for those digits.
If your teacher's a stickler for just having a foldr at the top-level, you can get
away with making go partial:
digits' :: Int -> [Int]
digits' n = foldr go [n] places where
places = replicate num_digits ()
num_digits | n > 0 = floor (logBase 10 $ fromIntegral n)
| otherwise = 0
go () (n:ds) = let (q,r) = n `quotRem` 10 in (q:r:ds)
This has slightly different behaviour on non-positive numbers:
>>> digits 1234567890
[1,2,3,4,5,6,7,8,9,0]
>>> digits' 1234567890
[1,2,3,4,5,6,7,8,9,0]
>>> digits 0
[]
>>> digits' 0
[0]
>>> digits (negate 1234567890)
[]
>>> digits' (negate 1234567890)
[-1234567890]
I've just started learning Haskell and found a strange thing.
Let we have a list:
ghci> [0,2..5]
[0,2,4]
It has 3 elements. When I use map with this list I get 3 element as output, for example:
ghci> map (+ 1) [0,2..5]
[1,3,5]
ghci> map (* 2) [0,2..5]
[0,4,8]
ghci> map (`div` 2) [0,2..5]
[0,1,2]
But when I use fractional division I get 4 elements in output list:
ghci> map (/ 2) [0,2..5]
[0.0,1.0,2.0,3.0]
ghci> length (map (/ 2) [0,2..5])
4
Could you please explain why map may return more elements then it was?
Thank you!
It's due to the implementation of Enum for Float and Double:
> [0,2..5] :: [Float]
[0.0,2.0,4.0,6.0]
It's not map doing it, but Float. Specifically, if you call enumFromThenTo 0 2 5 :: [Float], you'll get the same list. You'll see the same results for Double.
This is hinted at in the haskell report, but the behavior is definitely non-obvious. Essentially, it comes down to the implementation of numericEnumFromThenTo (we're getting into some Haskell internals here), which is used by the Enum Float instance:
numericEnumFromThenTo n n' m = takeWhile p (numericEnumFromThen n n')
where
p | n' >= n = (<= m + (n' - n) / 2)
| otherwise = (>= m + (n' - n) / 2)
numericEnumFromThen n m = iterate (+ (m - n)) n
So you have numericEnumFromThen 0.0 2.0 generating the list [0.0,2.0,4.0,6.0,8.0,...], then you do takeWhile p on that, which in this case is equivalent to the function \x -> x <= 5.0 + (2.0 - 0.0) / 2, or more simply \x -> x <= 6.0, which is why 6.0 is included in the output list of [0.0,2.0..5.0].
I can't explain why it's implemented this way, that's pretty baffling to me too, but hopefully I've answered the how for its implementation.
Here is non tail recursive function
alg :: Int -> Int
alg n = if n<7 then n else alg(n-1) * alg(n-2) * alg(n-4) * alg(n-6)
I've been stuck on this for a while, I get the basic idea of tail recursion, and how to do it for single call recursive function, but no clue how to do it for multi call one.
Even came up with this abomination
algT :: Int -> Int
algT n = tail1 n 0 where tail1 i r = tail1(i-1) r *
tail2 n 0 where tail2 i r = tail2(i-2) r *
tail3 n 0 where tail3 i r = tail3(i-4) r *
tail4 n 0 where tail4 i r = tail4(i-6) r
It doesnt work and obviously not how recursive function should look, had few other attempts, but all of them ended in infinite 100% cpu load loop...
Have you looked into Fibonacci in Haskell? It is a similar type of function. BTW tail recursion isn't quite the right term in Haskell, as multi-recursion functions can't really be done recursively but Haskell's lazy nature makes a similar but more powerful trick possible. Here is the standard one given:
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
Using the same trick on yours gives EDIT: As a function
alg :: Int -> Int
alg n = alg' !! (n - 1)
where alg' = 1 : 2 : 3 : 4 : 5 : 6 : zipWith4 (\a b c d -> a * b * c * d) (drop 5 alg') (drop 4 alg') (drop 2 alg') alg'
Note that you shouldn't use Int here, that isn't open ended and the 11th term will loop in an Int.
EDIT: Actually Int is even worse than I thought. Once you hit 32 2's in your result you will start returning 0 since every answer is 0 mod 2^32.
From your question it's not entirely clear what is the purpose of making your function tail-recusrive. If you are trying to reduce cpu/memory usage, then you should use memoization (mentioned in the Guvante's answer).
Meanwhile, there is a way to make almost any function tail-recursive, known as continuation-passing style. Your example written in the CPS looks like this:
alg_cps :: Integer -> (Integer->a) -> a
alg_cps n cont =
if n < 7
then cont n
else alg_cps (n - 1)
(\x1 -> alg_cps (n - 2)
(\x2 -> alg_cps (n - 4)
(\x3 -> alg_cps (n - 6)
(\x4 -> cont (x1*x2*x3*x4)))))
And to directly get the result you can call it with id as continuation:
alg_cps 20 id
Notice that this does not reduce algorithm complexity or memory usage compared to naive non-tail recursive implementation.
I think I have a solution, but it's not very elegant or pretty.
alg :: Int -> Int
alg n | n < 7 -> n
| otherwise -> alg' n (repeat 0)
alg' :: Int -> [Int] -> Int
alg' n [] = error "something has gone horribly wrong"
alg' n l#(x:y)
| n < 5 -> error "something else has gone horribly wrong"
| n == 6 -> product $ zipWith (^) [6,5..1] l
| otherwise -> alg' (n-1) $ zipWith (+) [x,x,0,x,0,x] (y ++ [0])
The idea is that you can keep track of how many times you're supposed to be multiplying each thing without actually doing any of the calculations until the very end. At any given time, you have information about how many times you've needed any of the next 6 values, and once you're below 7, you just raise 1-6 to the proper powers and take their product.
(I haven't actually tested this, but it seems right. And even if it's not I'm pretty sure the idea behind it is sound)
P.S. As #Guvante says, Int isn't a good choice here as it will quickly overflow. As a general rule I use Integer by default and only switch if I have a good reason.
Here is a possible solution.
let f = [1..6] ++ foldr1 (zipWith (*)) [f, drop 2 f, drop 4 f, drop 5 f]
or even:
let f = [1..6] ++ foldr1 (zipWith (*)) (map (flip drop $ f) [0,2,4,5])
I'm a C++ Programmer trying to teach myself Haskell and it's proving to be challenging grasping the basics of using functions as a type of loop. I have a large number, 50!, and I need to add the sum of its digits. It's a relatively easy loop in C++ but I want to learn how to do it in Haskell.
I've read some introductory guides and am able to get 50! with
sum50fac.hs::
fac 0 = 1
fac n = n * fac (n-1)
x = fac 50
main = print x
Unfortunately at this point I'm not entirely sure how to approach the problem.
Is it possible to write a function that adds (mod) x 10 to a value and then calls the same function again on x / 10 until x / 10 is less than 10? If that's not possible how should I approach this problem?
Thanks!
sumd 0 = 0
sumd x = (x `mod` 10) + sumd (x `div` 10)
Then run it:
ghci> sumd 2345
14
UPDATE 1:
This one doesn't generate thunks and uses accumulator:
sumd2 0 acc = acc
sumd2 x acc = sumd2 (x `div` 10) (acc + (x `mod` 10))
Test:
ghci> sumd2 2345 0
14
UPDATE 2:
Partially applied version in pointfree style:
sumd2w = (flip sumd2) 0
Test:
ghci> sumd2w 2345
14
I used flip here because function for some reason (probably due to GHC design) didn't work with accumulator as a first parameter.
Why not just
sumd = sum . map Char.digitToInt . show
This is just a variant of #ony's, but how I'd write it:
import Data.List (unfoldr)
digits :: (Integral a) => a -> [a]
digits = unfoldr step . abs
where step n = if n==0 then Nothing else let (q,r)=n`divMod`10 in Just (r,q)
This will product the digits from low to high, which while unnatural for reading, is generally what you want for mathematical problems involving the digits of a number. (Project Euler anyone?) Also note that 0 produces [], and negative numbers are accepted, but produce the digits of the absolute value. (I don't want partial functions!)
If, on the other hand, I need the digits of a number as they are commonly written, then I would use #newacct's method, since the problem is one of essentially orthography, not math:
import Data.Char (digitToInt)
writtenDigits :: (Integral a) => a -> [a]
writtenDigits = map (fromIntegral.digitToInt) . show . abs
Compare output:
> digits 123
[3,2,1]
> writtenDigits 123
[1,2,3]
> digits 12300
[0,0,3,2,1]
> writtenDigits 12300
[1,2,3,0,0]
> digits 0
[]
> writtenDigits 0
[0]
In doing Project Euler, I've actually found that some problems call for one, and some call for the other.
About . and "point-free" style
To make this clear for those not familiar with Haskell's . operator, and "point-free" style, these could be rewritten as:
import Data.Char (digitToInt)
import Data.List (unfoldr)
digits :: (Integral a) => a -> [a]
digits i = unfoldr step (abs i)
where step n = if n==0 then Nothing else let (q,r)=n`divMod`10 in Just (r,q)
writtenDigits :: (Integral a) => a -> [a]
writtenDigits i = map (fromIntegral.digitToInt) (show (abs i))
These are exactly the same as the above. You should learn that these are the same:
f . g
(\a -> f (g a))
And "point-free" means that these are the same:
foo a = bar a
foo = bar
Combining these ideas, these are the same:
foo a = bar (baz a)
foo a = (bar . baz) a
foo = bar . baz
The laster is idiomatic Haskell, since once you get used to reading it, you can see that it is very concise.
To sum up all digits of a number:
digitSum = sum . map (read . return) . show
show transforms a number to a string. map iterates over the single elements of the string (i.e. the digits), turns them into a string (e.g. character '1' becomes the string "1") and read turns them back to an integer. sum finally calculates the sum.
Just to make pool of solutions greater:
miterate :: (a -> Maybe (a, b)) -> a -> [b]
miterate f = go . f where
go Nothing = []
go (Just (x, y)) = y : (go (f x))
sumd = sum . miterate f where
f 0 = Nothing
f x = Just (x `divMod` 10)
Well, one, your Haskell function misses brackets, you need fac (n - 1). (oh, I see you fixed that now)
Two, the real answer, what you want is first make a list:
listdigits n = if n < 10 then [n] else (listdigits (n `div` 10)) ++ (listdigits (n `mod` 10))
This should just compose a list of all the digits (type: Int -> [Int]).
Then we just make a sum as in sum (listdigits n). And we should be done.
Naturally, you can generalize the example above for the list for many different radices, also, you can easily translate this to products too.
Although maybe not as efficient as the other examples, here is a different way of approaching it:
import Data.Char
sumDigits :: Integer -> Int
sumDigits = foldr ((+) . digitToInt) 0 . show
Edit: newacct's method is very similar, and I like it a bit better :-)