Skip to content

Instantly share code, notes, and snippets.

@guilleiguaran
Last active August 29, 2015 14:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save guilleiguaran/25f7211a85a97279c4be to your computer and use it in GitHub Desktop.
Save guilleiguaran/25f7211a85a97279c4be to your computer and use it in GitHub Desktop.
import Data.Monoid
-- Max: Monoid of Num under max.
data Max a = Max a | MinInfinity deriving Show
instance (Num a, Ord a) => Monoid (Max a) where
mempty = MinInfinity
MinInfinity `mappend` m = m
m `mappend` MinInfinity = m
Max x `mappend` Max y = Max (Prelude.max x y)
-- Min: Monoid of Num under min.
data Min a = Min a | Infinity deriving Show
instance (Num a, Ord a) => Monoid (Min a) where
mempty = Infinity
Infinity `mappend` m = m
m `mappend` Infinity = m
Min x `mappend` Min y = Min (Prelude.min x y)
-- Count monoid
newtype Count = Count Int deriving Show
instance Monoid Count where
mempty = Count 0
Count x `mappend` Count y = Count (x + y)
-- Compound Monoid: Num under average
newtype Mean a = Mean (Sum a, Count) deriving Show
instance (Num a) => Monoid (Mean a) where
mempty = Mean mempty
Mean x `mappend` Mean y = Mean (mappend x y)
-- Monoid functions
sum :: (Num a) => a -> Sum a
sum = Sum
product :: (Num a) => a -> Product a
product = Product
min :: (Ord a) => a -> Min a
min = Min
getMin (Min a) = a
max :: (Ord a) => a -> Max a
max = Max
getMax (Max a) = a
count :: a -> Count
count _ = Count 1
getCount (Count a) = a
mean :: (Num a) => a -> Mean a
mean v = Mean (Sum v, Count 1)
getMean (Mean (Sum t, Count n)) = t / fromIntegral n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment