import Prelude hiding (sum, mean)
reduce :: (a -> b -> b) -> b -> [a] -> b
reduce f b [] = b
reduce f b (a:as) = reduce f (f a b) as
sum = reduce (\ a b -> a + b) 0
count = reduce (\a b -> 1 + b) 0
mean = snd . reduce
(\ x (count, mean) ->
(count + 1, mean + (1 / (count + 1)) * (x - mean))
)
(0, 0)
-- produces descriptive statistics :: (count, sum, mean, variance)
stats = reduce
(\ x (count, sum, mean, var) ->
let k = 1 / (count + 1)
mean' = mean + k * (x - mean)
ssr' = (count - 1) * var + k * count * (x - mean) * (x - mean)
in (count + 1, sum + x, mean', ssr' / (max 1 count))
)
(0, 0, 0, 0)
main = do
print $ sum [1 .. 10]
print $ count [1 .. 10]
print $ mean [1 .. 10]
print $ stats [1 .. 10]