RosettaCodeData/Task/Averages-Simple-moving-average/Haskell/averages-simple-moving-average-3.hs
2016-12-05 22:15:40 +01:00

26 lines
780 B
Haskell

import Control.Monad
import Control.Monad.State
period :: Int
period = 3
type SMAState = [Float]
computeSMA :: Float -> State SMAState Float
computeSMA x = do
previousValues <- get
let values = previousValues ++ [x]
let newAverage = if length values <= period then (sum values) / (fromIntegral $ length remainingValues :: Float)
else (sum remainingValues) / (fromIntegral $ length remainingValues :: Float)
where remainingValues = dropIf period values
put $ dropIf period values
return newAverage
dropIf :: Int -> [a] -> [a]
dropIf x xs = drop ((length xs) - x) xs
demostrateSMA :: State SMAState [Float]
demostrateSMA = mapM computeSMA [1, 2, 3, 4, 5, 5, 4, 3, 2, 1]
main :: IO ()
main = print $ evalState demostrateSMA []