[Haskell-beginners] Averaging a string of numbers

goodman.m.w at gmail.com goodman.m.w at gmail.com
Sun Dec 11 04:21:58 CET 2011


Hi beginners list,

I want to take a string of numbers and return the average. It is a
string because I expect the input to be from STDIN or a file. I would
like it to handle infinite lists. Further, I create the Stats data
structure because later I will add support for other statistics, like
max, min, sum, prod, etc. The following code works, but I'm not sure
it's the proper way to do things in Haskell. For instance, maybe I
could use a fold method instead of the explicit recursion in getStats?
Could you please let me know if anything looks clunky or could be
improved (efficiency, aesthetics, etc)? Thank you

-- avg.hs
-- sm is sum, len is number of elements
data Stats = Stats { sm :: Double, len :: Int } deriving Show

getAverage :: String -> Double
getAverage str = (sm s / fromIntegral (len s))
                where s = (getStats . readNumbers . lines) str


getStats :: [Double] -> Stats
getStats []     = Stats 0.0 0
getStats [x]    = Stats x 1
getStats (x:xs) = Stats (x + (sm s)) ((len s) + 1)
                 where s = getStats xs

readNumbers :: [String] -> [Double]
readNumbers = map read
-- end avg.hs

And here's the results in ghci:

*Main> :load avg.hs
[1 of 1] Compiling Main             ( avg.hs, interpreted )
Ok, modules loaded: Main.
*Main> getAverage "0"
0.0
*Main> getAverage "1.4\n0.5\n85.2\n30.2\n-10"
21.46
*Main> getAverage ""
NaN

-- 
-Michael Wayne Goodman



More information about the Beginners mailing list