{-# OPTIONS_GHC -fglasgow-exts -Wall -fno-warn-orphans -fno-warn-unused-imports -fno-warn-missing-signatures #-} module Data.GMap.UnitMap (-- * UnitMap type UnitMap ) where import Data.GMap import qualified Data.Monoid as M (Monoid(..)) import qualified Data.Foldable as F (Foldable(..)) import Data.Typeable -- -fno-warn-unused-imports used because ghc currently gives spurious warning with this import -- See Tickets 1074 and 1148 import qualified Data.List as L (foldr) import GHC.Base hiding (map) import qualified Text.Read as R (Read(..),Lexeme(..),parens,prec,lexP,readListPrecDefault) import Data.Maybe -- | The default 'Map' type unit (empty tuple) keys. newtype UnitMap a = UnitMap (Maybe a) instance Map UnitMap () where empty = emptyUnitMap singleton = singletonUnitMap pair = pairUnitMap nonEmpty = nonEmptyUnitMap status = statusUnitMap addSize = addSizeUnitMap lookup = lookupUnitMap alter = alterUnitMap vennMaybe = vennMaybeUnitMap unionMaybe = unionMaybeUnitMap isSubsetOf = isSubsetOfUnitMap isSubmapOf = isSubmapOfUnitMap mapMaybe = mapMaybeUnitMap mapWithKey = mapWithKeyUnitMap mapWithKey' = mapWithKeyUnitMap' filter = filterUnitMap foldKeys = foldKeysUnitMap foldElems = foldElemsUnitMap foldAssocs = foldAssocsUnitMap foldKeys' = foldKeysUnitMap foldElems' = foldElemsUnitMap foldAssocs' = foldAssocsUnitMap foldElemsUInt = foldElemsUIntUnitMap valid = validUnitMap instance OrderedMap UnitMap () where compareKey = compareKeyUnitMap -- fromAssocsAscWith -- fromAssocsDescWith -- fromAssocsAscMaybe -- fromAssocsDescMaybe foldElemsAsc = foldElemsUnitMap foldElemsDesc = foldElemsUnitMap foldKeysAsc = foldKeysUnitMap foldKeysDesc = foldKeysUnitMap foldAssocsAsc = foldAssocsUnitMap foldAssocsDesc = foldAssocsUnitMap foldElemsAsc' = foldElemsUnitMap foldElemsDesc' = foldElemsUnitMap foldKeysAsc' = foldKeysUnitMap foldKeysDesc' = foldKeysUnitMap foldAssocsAsc' = foldAssocsUnitMap foldAssocsDesc' = foldAssocsUnitMap -- | See 'Map' class method 'empty'. emptyUnitMap :: UnitMap a emptyUnitMap = UnitMap Nothing {-# INLINE emptyUnitMap #-} -- | See 'Map' class method 'singleton'. singletonUnitMap :: () -> a -> UnitMap a singletonUnitMap _ a = UnitMap (Just a) {-# INLINE singletonUnitMap #-} -- | See 'Map' class method 'pair'. pairUnitMap :: () -> () -> Maybe (a -> a -> UnitMap a) pairUnitMap _ _ = Nothing -- Args are always equal!! {-# INLINE pairUnitMap #-} -- | See 'Map' class method 'nonEmpty'. nonEmptyUnitMap :: UnitMap a -> Maybe (UnitMap a) nonEmptyUnitMap (UnitMap Nothing) = Nothing nonEmptyUnitMap ugt = Just ugt -- | See 'Map' class method 'status'. statusUnitMap :: UnitMap a -> Status () a statusUnitMap (UnitMap (Just a)) = One () a statusUnitMap _ = None -- | See 'Map' class method 'addSize'. addSizeUnitMap :: UnitMap a -> Int# -> Int# addSizeUnitMap (UnitMap Nothing) n = n addSizeUnitMap _ n = (n +# 1#) -- | See 'Map' class method 'Data.GMap.lookup'. lookupUnitMap :: () -> UnitMap a -> Maybe a lookupUnitMap _ (UnitMap mba) = mba {-# INLINE lookupUnitMap #-} alterUnitMap :: (Maybe a -> Maybe a) -> () -> UnitMap a -> UnitMap a alterUnitMap f _ (UnitMap mba) = UnitMap (f mba) -- | See 'Map' class method 'vennMaybe' vennMaybeUnitMap :: (a -> b -> Maybe c) -> UnitMap a -> UnitMap b -> (UnitMap a, UnitMap c, UnitMap b) vennMaybeUnitMap _ (UnitMap Nothing) (UnitMap Nothing) = (UnitMap Nothing, UnitMap Nothing, UnitMap Nothing) vennMaybeUnitMap _ (UnitMap ja ) (UnitMap Nothing) = (UnitMap ja , UnitMap Nothing, UnitMap Nothing) vennMaybeUnitMap _ (UnitMap Nothing) (UnitMap jb ) = (UnitMap Nothing, UnitMap Nothing, UnitMap jb ) vennMaybeUnitMap f (UnitMap (Just a)) (UnitMap (Just b)) = (UnitMap Nothing, UnitMap (f a b), UnitMap Nothing) -- | See 'Map' class method 'unionMaybe'. unionMaybeUnitMap :: (a -> a -> Maybe a) -> UnitMap a -> UnitMap a -> UnitMap a unionMaybeUnitMap _ (UnitMap Nothing) (UnitMap Nothing) = UnitMap Nothing unionMaybeUnitMap _ (UnitMap ja ) (UnitMap Nothing) = UnitMap ja unionMaybeUnitMap _ (UnitMap Nothing) (UnitMap jb ) = UnitMap jb unionMaybeUnitMap f (UnitMap (Just a)) (UnitMap (Just b)) = UnitMap (f a b) -- | See 'Map' class method 'isSubsetOf'. isSubsetOfUnitMap :: UnitMap a -> UnitMap b -> Bool isSubsetOfUnitMap (UnitMap Nothing ) _ = True isSubsetOfUnitMap (UnitMap (Just _)) (UnitMap (Just _)) = True isSubsetOfUnitMap _ _ = False -- | See 'Map' class method 'isSubmapOf'. isSubmapOfUnitMap :: (a -> b -> Bool) -> UnitMap a -> UnitMap b -> Bool isSubmapOfUnitMap _ (UnitMap Nothing ) _ = True isSubmapOfUnitMap f (UnitMap (Just a)) (UnitMap (Just b)) = f a b isSubmapOfUnitMap _ _ _ = False -- | See 'Map' class method 'Data.GMap.mapMaybe'. mapMaybeUnitMap :: (a -> Maybe b) -> UnitMap a -> UnitMap b mapMaybeUnitMap f (UnitMap (Just a)) = UnitMap (f a) mapMaybeUnitMap _ _ = emptyUnitMap -- | See 'Map' class method 'mapWithKey'. mapWithKeyUnitMap :: (() -> a -> b) -> UnitMap a -> UnitMap b mapWithKeyUnitMap f (UnitMap (Just a)) = UnitMap (Just (f () a)) mapWithKeyUnitMap _ _ = emptyUnitMap -- | See 'Map' class method 'mapWithKey''. mapWithKeyUnitMap' :: (() -> a -> b) -> UnitMap a -> UnitMap b mapWithKeyUnitMap' f (UnitMap (Just a)) = let b = f () a in b `seq` UnitMap (Just b) mapWithKeyUnitMap' _ _ = emptyUnitMap -- | See 'Map' class method 'Data.GMap.filter'. filterUnitMap :: (a -> Bool) -> UnitMap a -> UnitMap a filterUnitMap p u@(UnitMap (Just a)) = if p a then u else emptyUnitMap filterUnitMap _ _ = emptyUnitMap -- | See 'Map' class method 'foldElems' foldKeysUnitMap :: (() -> b -> b) -> b -> UnitMap a -> b foldKeysUnitMap f b (UnitMap mba) = case mba of Just _ -> f () b Nothing -> b -- | See 'Map' class method 'foldElems' foldElemsUnitMap :: (a -> b -> b) -> b -> UnitMap a -> b foldElemsUnitMap f b (UnitMap mba) = case mba of Just a -> f a b Nothing -> b -- | See 'Map' class method 'foldAssocs' foldAssocsUnitMap :: (() -> a -> b -> b) -> b -> UnitMap a -> b foldAssocsUnitMap f b (UnitMap mba) = case mba of Just a -> f () a b Nothing -> b -- | See 'Map' class method 'foldElemsInt#'. foldElemsUIntUnitMap :: (a -> Int# -> Int#) -> Int# -> UnitMap a -> Int# foldElemsUIntUnitMap f n (UnitMap mba) = case mba of Just a -> f a n Nothing -> n -- | See 'Map' class method 'valid'. validUnitMap :: UnitMap a -> Maybe String validUnitMap _ = Nothing -- Always valid! {-# INLINE validUnitMap #-} -- | See 'Map' class method 'compareKey' compareKeyUnitMap :: UnitMap a -> () -> () -> Ordering compareKeyUnitMap _ _ _ = EQ -------------------------------------------------------------------------- -- OTHER INSTANCES -- -------------------------------------------------------------------------- -------- -- Eq -- -------- instance Eq a => Eq (UnitMap a) where UnitMap mba0 == UnitMap mba1 = mba0 == mba1 --------- -- Ord -- --------- instance Ord a => Ord (UnitMap a) where compare (UnitMap Nothing ) (UnitMap Nothing ) = EQ compare (UnitMap Nothing ) (UnitMap (Just _ )) = LT compare (UnitMap (Just _ )) (UnitMap Nothing ) = GT compare (UnitMap (Just a0)) (UnitMap (Just a1)) = compare a0 a1 ---------- -- Show -- ---------- instance Show a => Show (UnitMap a) where showsPrec d mp = showParen (d > 10) $ showString "fromAssocs " . shows (assocs mp) ---------- -- Read -- ---------- instance R.Read a => R.Read (UnitMap a) where readPrec = R.parens $ R.prec 10 $ do R.Ident "fromAssocs" <- R.lexP xs <- R.readPrec return (fromAssocs xs) readListPrec = R.readListPrecDefault ------------------------ -- Typeable/Typeable1 -- ------------------------ instance Typeable1 UnitMap where typeOf1 _ = mkTyConApp (mkTyCon "Data.GMap.UnitMap.UnitMap") [] -------------- instance Typeable a => Typeable (UnitMap a) where typeOf = typeOfDefault ------------- -- Functor -- ------------- instance Functor (UnitMap) where -- fmap :: (a -> b) -> UnitMap a -> UnitMap b fmap = Data.GMap.map -- The lazy version ----------------- -- Data.Monoid -- ----------------- instance (M.Monoid a) => M.Monoid (UnitMap a) where -- mempty :: UnitMap a mempty = emptyUnitMap -- mappend :: UnitMap a -> UnitMap a -> UnitMap a mappend map0 map1 = union M.mappend map0 map1 -- mconcat :: [UnitMap a] -> UnitMap a mconcat maps = L.foldr (union M.mappend) emptyUnitMap maps ------------------- -- Data.Foldable -- ------------------- instance F.Foldable (UnitMap) where -- fold :: Monoid m => UnitMap m -> m fold mp = foldElemsUnitMap M.mappend M.mempty mp -- foldMap :: Monoid m => (a -> m) -> UnitMap a -> m foldMap f mp = foldElemsUnitMap (\a b -> M.mappend (f a) b) M.mempty mp -- foldr :: (a -> b -> b) -> b -> UnitMap a -> b foldr f b0 mp = foldElemsUnitMap f b0 mp -- foldl :: (a -> b -> a) -> a -> UnitMap b -> a foldl f b0 mp = foldElemsUnitMap (flip f) b0 mp {- ToDo: Implement properly. Meantime Foldable class has suitable defaults via lists. -- foldr1 :: (a -> a -> a) -> UnitMap a -> a foldr1 = undefined -- foldl1 :: (a -> a -> a) -> UnitMap a -> a foldl1 = undefined -}