module Util.HasSize where -- this point of this module is not only to share the 'size' syntax, but to -- provide optimally lazy versions of size comparasin functions when dealing -- with lazy structures. This is especially useful when having to compare the -- size of possibly long lists. -- it is up to each instance to decide what 'size' means import qualified Data.Map(Map,size,null) import qualified Data.Set(Set,size,null) import qualified Data.IntMap(IntMap,size,null) import qualified Data.IntSet(IntSet,size,null) class IsEmpty a where isEmpty :: a -> Bool class HasSize a where size :: a -> Int sizeEQ :: Int -> a -> Bool sizeGT :: Int -> a -> Bool sizeLT :: Int -> a -> Bool sizeGTE :: Int -> a -> Bool sizeLTE :: Int -> a -> Bool sizeEQ s x = size x == s sizeGT s x = size x > s sizeLT s x = size x < s sizeGTE s x = not $ sizeLT s x sizeLTE s x = not $ sizeGT s x genSize :: (Integral b,HasSize a) => a -> b genSize = fromIntegral . Util.HasSize.size instance HasSize [x] where size = length sizeEQ n _ | n < 0 = False sizeEQ n xs = f n xs where f 0 [] = True f _ [] = False f 0 _ = False f n (_:xs) = sizeEQ (n - 1) xs sizeGT n _ | n < 0 = True sizeGT n xs = f n xs where f 0 (_:_) = True f n [] = False f n (_:xs) = f (n - 1) xs sizeLT n _ | n <= 0 = False sizeLT n xs = f n xs where f 0 _ = False f _ [] = True f n (_:xs) = f (n - 1) xs instance HasSize (Data.Map.Map a b) where size = Data.Map.size instance HasSize (Data.Set.Set a) where size = Data.Set.size instance HasSize (Data.IntMap.IntMap v) where size = Data.IntMap.size instance HasSize Data.IntSet.IntSet where size = Data.IntSet.size instance (HasSize a,HasSize b) => HasSize (Either a b) where size (Left x) = size x size (Right y) = size y sizeEQ s (Left x) = sizeEQ s x sizeEQ s (Right x) = sizeEQ s x sizeLT s (Left x) = sizeLT s x sizeLT s (Right x) = sizeLT s x sizeGT s (Left x) = sizeGT s x sizeGT s (Right x) = sizeGT s x instance (HasSize a,HasSize b) => HasSize (a,b) where size (x,y) = size x + size y instance (HasSize a,HasSize b,HasSize c) => HasSize (a,b,c) where size (x,y,z) = size x + size y + size z instance IsEmpty [x] where isEmpty = null instance IsEmpty (Data.Map.Map a b) where isEmpty = Data.Map.null instance IsEmpty (Data.Set.Set a) where isEmpty = Data.Set.null instance IsEmpty (Data.IntMap.IntMap v) where isEmpty = Data.IntMap.null instance IsEmpty Data.IntSet.IntSet where isEmpty = Data.IntSet.null instance (IsEmpty a,IsEmpty b) => IsEmpty (a,b) where isEmpty (x,y) = isEmpty x && isEmpty y instance (IsEmpty a,IsEmpty b,IsEmpty c) => IsEmpty (a,b,c) where isEmpty (x,y,z) = isEmpty x && isEmpty y && isEmpty z