views:

259

answers:

8

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 :-))

A: 

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...).

danatel
+2  A: 

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.

Matt Ellen
i dont understand why it is like that, please see this: http://stackoverflow.com/questions/2027570/haskell-learning-exercise-gives-strange-results/2027891#2027891)(it's a link for my comment below)
moshe
+5  A: 
  1. You get the wrong answers for your first attempt, because you use an incorrect formula. Garbage in, garbage out. (Other people have covered this.)

  2. 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.

  3. No indentation is used or required here, so the spaces -v- tabs issue doesn't arise.

Dave Hinton
wouldn't be more helpful to provide a correct answer?
nont
If you think any part of my answer is incorrect, please point out what I have said that is wrong, and why. If you are referring to my answer to the first part of the OP's question --- no, I don't think it's helpful to repeat what other people had already said as well as I could have done in their answers before I even read the question.
Dave Hinton
+1  A: 

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.

Dale Hagglund
the designers of SO wanted to discourage the usage of `'` in function and variable names, so they made it come at the penalty of coloring your code with weird colors. I recommend adhering to their style and trying to avoid the usage of `'` in code snippets.
yairchu
Well, the use of primed names is at least somewhat common in Haskell, and I guess I didn't quite look at the preview closely enough to really notice the highlighting changes.
Dale Hagglund
This seems like the simplest answer that efficiently does what the OP asked for.
nont
thanks for your answer.i checked it out and it's working :-).also, please let me see if i understand your answer.in this example, i think, we don't get out from the recursion's, and the function finished when we are in the inner recursion.there(in the inner recursion) the thunk of (((0 + 2) + 4) + 6) - which is the sum variable - is compute, and the thunk of (((0 + 1) + 1) + 1) - which is the len variable - is compute also. after the computation of both the sum and len, the divide is come to reality and we get the answer.am i right? :-).
moshe
A: 

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 :-).

moshe
your expansion on the right is incorrect. mean [6] == mean [6], but you have mean [6] on the left = 6, but on the right mean [6] = 1. It can't be both
Matt Ellen
Your substitution is wrong. For example, you should use"(6 + 0 ) / (1 + 0)" as a whole to repleace the part "mean [6 ]" of "(4 + mean [6]) / (1 + mean [ 6])".
yehnan
thanks for your answers :-)
moshe
Apropos why it didn't work yesterday: I'm no expert by a long shot, but a lot of my initial confusion in Haskell had to do with type inference. For instance, the following will fail in your code: mean [2::Int, 4::Int, 6::Int]. GHC will complain that an expected type doesn't match an inferred type (i.e., the statically-typed Int). When I did this exercise, I typed it [Int] -> Double, and then pulled my hair out before I figured out I needed to use fromIntegral to get the types to play nicely together. The type system in Haskell is stronger (in every sense) than anything I've ever seen.
rtperson
or you can do a type like this:mean :: [Double] -> Double, so all the "Int's" are Doubles.now you dont need the fromIntegral, because it's all Double.
moshe
+2  A: 

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
ephemient
This all makes sense, but isn't a rather complicated path to take? (what with uncurry and the lambda expression) The OP seems very new to Haskell, so I'm just thinking that a simpler answer would server him better.
nont
thanks for your answer :-).i thought that the divide is done just when we get to to the start again(after we get out from the recursion's we had).with your example i see that every exit from one recursion we do the divide and the result of the divide passing up to the next recursion.am i right?another thing that i don't understand is why the end resault is 24/17?how did you come to 24/17 from (2 + 10/7) / (1 + 10/7)?please explain :-)
moshe
Yes. There's nothing special at all about recursion; it just happens to be a call to a function with the same name as what you're in now. The last bit is just simple math: (2+10/7)/(1+10/7) = (24/7)/(17/7) = 24/7
ephemient
in "Yes" you mean i'm right about my first question?i mean: every exit from one recursion we do the divide and the result of the divide passing up to the next recursion?(sorry for nagging, but i want to be sure about that :-)).about the simple math, i'm sorry, but it seems that even simple math i don't understand :-D.but my friend helped me and i understood eventually.thanks a lot :-).
moshe
Yes to the first question. You can imagine that you have many functions defined: `mean1` calls `mean2` calls `mean3`, and they're completely unrelated. I mistyped the comment (I got it correct in my answer above), but didn't you learn how to divide fractions in elementary school?
ephemient
well, i learned it in school but it was so many years ago, and i have to refresh it :-)thanks :-)
moshe
+1  A: 

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 }
primodemus
LOL. Even better if you used Lennart's BASIC http://augustss.blogspot.com/2009/02/more-basic-not-that-anybody-should-care.html :-D
ephemient
+1  A: 

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
Greg Bacon
thanks for your answer :-).i'm newbie, so i didn't understand some of the things you typed, but maybe in the future, when i will(hope so) finish the book, i will understand it all :-)
moshe
You're welcome! Keep this info in the back of your mind for when you need to perform arithmetic on values of different numeric types.
Greg Bacon