{-# LANGUAGE FlexibleInstances #-} {- | Typeclass that tells how to measure different values as 'Monoid'. -} module Treap.Measured ( Measured (..) ) where import Data.Functor.Identity (Identity (..)) import Data.Monoid (All (..), Any (..), Dual (..), Endo (..), First (..), Last (..), Product (..), Sum (..)) import Data.Semigroup (Max (..), Min (..)) {- | This typeclass allows to specify how to convert value of type @a@ into monoidal value of type @m@. -} class Monoid m => Measured m a where measure :: a -> m -- | Measure every 'Monoid' as itself. instance Monoid a => Measured (Identity a) a where measure = Identity {-# INLINE measure #-} -- | Measure every 'Monoid' as its dual. instance Monoid a => Measured (Dual a) a where measure = Dual {-# INLINE measure #-} -- | Measure every endomorphic function with compostion. instance Measured (Endo a) (a -> a) where measure = Endo {-# INLINE measure #-} -- | Measure every numeric value with addition. instance Num a => Measured (Sum a) a where measure = Sum {-# INLINE measure #-} -- | Measure every numeric value with multiplication. instance Num a => Measured (Product a) a where measure = Product {-# INLINE measure #-} -- | Measure every comparable value with minimum. instance (Ord a, Bounded a) => Measured (Min a) a where measure = Min {-# INLINE measure #-} -- | Measure every comparable value with maximum. instance (Ord a, Bounded a) => Measured (Max a) a where measure = Max {-# INLINE measure #-} -- | Measure every value as the 'First' monoid. instance Measured (First a) a where measure = First . Just {-# INLINE measure #-} -- | Measure every value as the 'Last' monoid. instance Measured (Last a) a where measure = Last . Just {-# INLINE measure #-} -- | Measure boolean value with '&&'. instance Measured All Bool where measure = All -- | Measure boolean value with '||'. instance Measured Any Bool where measure = Any