module Helpers(maybeHead, headOrElse, statefully, mapTuple, statefullyTakeWhile, histogram) where import Data.Maybe import qualified Data.Map as Map maybeHead :: [a] -> Maybe a maybeHead [] = Nothing maybeHead (x:xs) = Just x headOrElse :: a -> [a] -> a headOrElse d ls = fromMaybe d (maybeHead ls) statefully :: (g -> (a, g)) -> Int -> g -> ([a], g) statefully f n g0 = case n of 0 -> ([], g0) x -> (r:rest, g2) where (r, g1) = f g0 (rest, g2) = statefully f (n-1) g1 statefullyTakeWhile :: (g -> (a, g)) -> ([a] -> Bool) -> g -> ([a], g) statefullyTakeWhile f p g0 = r ([], g0) where r (list, g1) | p list = (list, g1) | otherwise = mapTuple (\l -> l:list) (id) (f g1) mapTuple :: (a -> b) -> (c -> d) -> (a, c) -> (b, d) mapTuple f g (x, y) = (f x, g y) histogram :: Double -> [Double] -> [Int] histogram precision ls = map lookup0 [0..limit] where limit = truncate $ (1.0 / precision) divs = map (\x -> x / precision) ls ints = map (truncate) divs m = foldl (\b a -> Map.insert a ((fromMaybe 0 (Map.lookup a b))+1) b) Map.empty ints lookup0 = (\x -> fromMaybe 0 $ Map.lookup x m) toDbl = fromInteger . toInteger