module Data.Count ( Countable(..), toPos, fromPos, count, allValues ) where import Data.Count.Counter import Data.Int -- | Class and instances for producing 'Counter's by type. class Countable a where counter :: Counter a -- | Overloaded 'cToPos'. toPos :: Countable a => a -> Integer -- | Overloaded 'cFromPos'. fromPos :: Countable a => Integer -> a -- | Overloaded 'cCount'. Doesn't attempt to reduce the dummy value given. count :: Countable a => a -> Maybe Integer toPos = cToPos counter fromPos = cFromPos counter count a = cCount c where c = counter -- monomorphise constr = a `asTypeOf` cFromPos c 0 -- | Overloaded 'allValuesFor'. allValues :: Countable a => [a] allValues = allValuesFor counter instance Countable Integer where counter = integerCounter instance Countable Bool where counter = boundedEnumCounter instance Countable Char where counter = boundedEnumCounter -- not portable instance Countable Int where counter = boundedEnumCounter instance Countable Int8 where counter = boundedEnumCounter instance Countable Int16 where counter = boundedEnumCounter instance Countable Int32 where counter = boundedEnumCounter instance Countable Int64 where counter = boundedEnumCounter instance Countable () where counter = unitCounter instance (Countable a, Countable b) => Countable (Either a b) where counter = sumCounter counter counter instance (Countable a, Countable b) => Countable (a, b) where counter = prodCounter counter counter instance (Countable a, Countable b, Countable c) => Countable (a, b, c) where counter = isoCounter (prodCounter counter (prodCounter counter counter)) f g where f (a, b, c) = (a, (b, c)) g (a, (b, c)) = (a, b, c) instance (Countable a, Countable b, Countable c, Countable d) => Countable (a, b, c, d) where counter = isoCounter (prodCounter counter (prodCounter counter (prodCounter counter counter))) f g where f (a, b, c, d) = (a, (b, (c, d))) g (a, (b, (c, d))) = (a, b, c, d) class Countable1 f where counter1 :: Counter a -> Counter (f a) instance Countable a => Countable [a] where counter = listCounter counter instance Countable a => Countable (Maybe a) where counter = maybeCounter counter