Saturday 4 June 2016

Haskell: Write a function that computes the mean of a list

meanUtil.hs
{- Calculate length of the list -}
lengthOfList :: [a] -> Integer
lengthOfList [] = 0
lengthOfList (x:xs) = 1 + lengthOfList xs

{- Sum of list elements -}
sumOfElements :: [Double] -> Double
sumOfElements [] = 0
sumOfElements (x:xs) =  x + sumOfElements xs

{-Calculate mean of a list -}
mean :: [Double] -> Double
mean [] = 0
mean xs = (sumOfElements xs) / fromIntegral (lengthOfList xs)

Prelude> :load meanUtil.hs
[1 of 1] Compiling Main             ( meanUtil.hs, interpreted )
Ok, modules loaded: Main.
*Main> 
*Main> mean []
0.0
*Main> 
*Main> mean [2, 3, 5]
3.3333333333333335
*Main> 
*Main> mean [2, 3, 5.234]
3.4113333333333333
*Main> 
*Main> mean [2, 3, 5.234, 7]
4.3085
*Main>


Observe above program, I am iterating through the list twice, once to calculate the sum of elements of a list and once to calculate the length of a list, actually we can calculate both sum and length in single traversal.

meanUtil.hs
{- Return (lengthOfList, sumOfElementsOfList)-}
lenAndSum :: [Double] -> (Integer, Double)
lenAndSum [] = (0,0.0)
lenAndSum xs = getLenSum 0 0.0 xs

{- Return (lengthOfList, sumOfElementsOfList)-}
getLenSum :: Integer -> Double -> [Double] -> (Integer, Double)
getLenSum len total [] = (len, total) 
getLenSum len total (x:xs) = getLenSum (1+len) (total+x) xs

{- Mean of the list -}
mean :: [Double] -> Double
mean [] = 0.0
mean xs = let (len, total) = lenAndSum xs
          in
             (total / fromIntegral len)

*Main> :load meanUtil.hs
[1 of 1] Compiling Main             ( meanUtil.hs, interpreted )
Ok, modules loaded: Main.
*Main> 
*Main> mean []
0.0
*Main> 
*Main> mean [2, 3, 5]
3.3333333333333335
*Main> 
*Main> mean [2, 3, 5.234]
3.4113333333333333
*Main> 
*Main> mean [2, 3, 5.234, 7]
4.3085
*Main> 



Previous                                                 Next                                                 Home

No comments:

Post a Comment