{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Data.Histogram.Bin.BinEnum ( BinEnum(..) , binEnum , binEnumFull ) where import Control.DeepSeq (NFData(..)) import Control.Monad (liftM) import Data.Data (Data,Typeable) import Text.Read (Read(..)) import Data.Histogram.Bin.Classes import Data.Histogram.Bin.BinI import Data.Histogram.Parse -- | Bin for types which are instnaces of Enum type class. Value are -- converted to 'Int' using 'fromEnum' first and then binned. newtype BinEnum a = BinEnum BinI deriving (Eq,Data,Typeable,BinEq) -- | Create enum based bin binEnum :: Enum a => a -> a -> BinEnum a binEnum a b = BinEnum $ binI (fromEnum a) (fromEnum b) -- | Use full range of data binEnumFull :: (Enum a, Bounded a) => BinEnum a binEnumFull = binEnum minBound maxBound instance Enum a => Bin (BinEnum a) where type BinValue (BinEnum a) = a toIndex (BinEnum b) = toIndex b . fromEnum fromIndex (BinEnum b) = toEnum . fromIndex b inRange (BinEnum b) = inRange b . fromEnum nBins (BinEnum b) = nBins b instance (Enum a, Ord a) => IntervalBin (BinEnum a) where binInterval b x = (n,n) where n = fromIndex b x instance (Enum a, Ord a) => Bin1D (BinEnum a) where lowerLimit (BinEnum b) = toEnum $ lowerLimit b upperLimit (BinEnum b) = toEnum $ upperLimit b instance (Enum a, Ord a) => SliceableBin (BinEnum a) where unsafeSliceBin i j (BinEnum b) = BinEnum $ unsafeSliceBin i j b instance Show (BinEnum a) where show (BinEnum b) = "# BinEnum\n" ++ show b instance Read (BinEnum a) where readPrec = keyword "BinEnum" >> liftM BinEnum readPrec instance NFData (BinEnum a)