{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE GADTs #-}
module Data.Dependent.Map.Monoidal where
import Data.Aeson
import Data.Coerce
import Data.Constraint.Extras
import Data.Constraint.Forall
import Data.Dependent.Map (DMap)
import qualified Data.Dependent.Map as DMap
import Data.Dependent.Sum
import Data.Dependent.Sum.Orphans ()
import Data.GADT.Compare
import Data.GADT.Show
import Data.Maybe
import Data.Semigroup
import Data.Some hiding (This)
import Text.Read
import Prelude hiding (lookup, map)
newtype MonoidalDMap (f :: k -> *) (g :: k -> *) = MonoidalDMap { unMonoidalDMap :: DMap f g }
newtype FakeDSum f g = FakeDSum { unFakeDSum :: DSum f g }
instance (GEq f, Has' Eq f g) => Eq (FakeDSum f g) where
FakeDSum ((k :: k a) :=> v) == FakeDSum (k' :=> v') = case geq k k' of
Nothing -> False
Just Refl -> has' @Eq @g k (v == v')
instance (GCompare f, Has' Eq f g, Has' Ord f g) => Ord (FakeDSum f g) where
compare (FakeDSum (k :=> v)) (FakeDSum (k' :=> v')) = case gcompare k k' of
GLT -> LT
GGT -> GT
GEQ -> has' @Ord @g k (compare v v')
instance (ForallF Show f, Has' Show f g) => Show (FakeDSum f g) where
showsPrec p (FakeDSum ((k :: f a) :=> v)) = showParen (p >= 10)
( whichever @Show @f @a (showsPrec 0 k)
. showString " :=> "
. has' @Show @g k (showsPrec 1 v)
)
instance (GRead f, Has' Read f g) => Read (FakeDSum f g) where
readsPrec p = readParen (p > 1) $ \s ->
concat
[ getGReadResult withTag $ \tag ->
[ (FakeDSum (tag :=> val), rest'')
| (val, rest'') <- has' @Read @g tag $ readsPrec 1 rest'
]
| (withTag, rest) <- greadsPrec p s
, (":=>", rest') <- lex rest
]
instance forall f g. (Has' Eq f g, GCompare f) => Eq (MonoidalDMap f g) where
MonoidalDMap m == MonoidalDMap m' =
(coerce (DMap.toList m) :: [FakeDSum f g]) == (coerce (DMap.toList m'))
instance forall f g. (Has' Eq f g, Has' Ord f g, GCompare f) => Ord (MonoidalDMap f g) where
compare (MonoidalDMap m) (MonoidalDMap m') =
compare (coerce (DMap.toList m) :: [FakeDSum f g]) (coerce (DMap.toList m'))
instance (Show (FakeDSum k f)) => Show (MonoidalDMap k f) where
showsPrec p m = showParen (p>10)
( showString "fromList "
. showsPrec 11 (coerce (toList m) :: [FakeDSum k f])
)
instance (GCompare k, Read (FakeDSum k f)) => Read (MonoidalDMap k f) where
readPrec = parens $ prec 10 $ do
Ident "fromList" <- lexP
xs <- readPrec
return . MonoidalDMap . DMap.fromList $ coerce (xs :: [FakeDSum k f])
readListPrec = readListPrecDefault
deriving instance (ToJSON (DMap f g)) => ToJSON (MonoidalDMap f g)
instance (Has' Semigroup f g, GCompare f) => Semigroup (MonoidalDMap f g) where
(MonoidalDMap m) <> (MonoidalDMap n) =
MonoidalDMap (DMap.unionWithKey (\f (u :: g a) v -> has' @Semigroup @g f (u <> v)) m n)
instance (Has' Semigroup f g, GCompare f) => Monoid (MonoidalDMap f g) where
mempty = empty
mappend m n = m <> n
deriving instance (FromJSON (DMap f g)) => FromJSON (MonoidalDMap f g)
empty :: MonoidalDMap k f
empty = MonoidalDMap DMap.empty
singleton :: k v -> f v -> MonoidalDMap k f
singleton k x = MonoidalDMap (DMap.singleton k x)
null :: MonoidalDMap k f -> Bool
null (MonoidalDMap m) = DMap.null m
size :: MonoidalDMap k f -> Int
size (MonoidalDMap m) = DMap.size m
lookup :: forall k f v. GCompare k => k v -> MonoidalDMap k f -> Maybe (f v)
lookup k (MonoidalDMap m) = DMap.lookup k m
deleteFindMin :: MonoidalDMap k f -> (DSum k f, MonoidalDMap k f)
deleteFindMin (MonoidalDMap m) =
case DMap.deleteFindMin m of
(x, m') -> (x, MonoidalDMap m')
minViewWithKey :: forall k f . MonoidalDMap k f -> Maybe (DSum k f, MonoidalDMap k f)
minViewWithKey (MonoidalDMap m) =
case DMap.minViewWithKey m of
Nothing -> Nothing
Just (x, m') -> Just (x, MonoidalDMap m')
maxViewWithKey :: forall k f . MonoidalDMap k f -> Maybe (DSum k f, MonoidalDMap k f)
maxViewWithKey (MonoidalDMap m) =
case DMap.maxViewWithKey m of
Nothing -> Nothing
Just (x, m') -> Just (x, MonoidalDMap m')
deleteFindMax :: MonoidalDMap k f -> (DSum k f, MonoidalDMap k f)
deleteFindMax (MonoidalDMap m) =
case DMap.deleteFindMax m of
(x, m') -> (x, MonoidalDMap m')
member :: GCompare k => k a -> MonoidalDMap k f -> Bool
member k = isJust . lookup k
notMember :: GCompare k => k v -> MonoidalDMap k f -> Bool
notMember k m = not (member k m)
find :: GCompare k => k v -> MonoidalDMap k f -> f v
find k m = case lookup k m of
Nothing -> error "MonoidalDMap.find: element not in the map"
Just v -> v
findWithDefault :: GCompare k => f v -> k v -> MonoidalDMap k f -> f v
findWithDefault def k m = case lookup k m of
Nothing -> def
Just v -> v
insert :: forall k f v. GCompare k => k v -> f v -> MonoidalDMap k f -> MonoidalDMap k f
insert k v (MonoidalDMap m) = MonoidalDMap (DMap.insert k v m)
insertWith :: GCompare k => (f v -> f v -> f v) -> k v -> f v -> MonoidalDMap k f -> MonoidalDMap k f
insertWith f k v (MonoidalDMap m) = MonoidalDMap (DMap.insertWith f k v m)
insertWith' :: GCompare k => (f v -> f v -> f v) -> k v -> f v -> MonoidalDMap k f -> MonoidalDMap k f
insertWith' f k v (MonoidalDMap m) = MonoidalDMap (DMap.insertWith' f k v m)
insertWithKey :: forall k f v. GCompare k => (k v -> f v -> f v -> f v) -> k v -> f v -> MonoidalDMap k f -> MonoidalDMap k f
insertWithKey f k v (MonoidalDMap m) = MonoidalDMap (DMap.insertWithKey f k v m)
insertWithKey' :: forall k f v. GCompare k => (k v -> f v -> f v -> f v) -> k v -> f v -> MonoidalDMap k f -> MonoidalDMap k f
insertWithKey' f k v (MonoidalDMap m) = MonoidalDMap (DMap.insertWithKey' f k v m)
insertLookupWithKey :: forall k f v. GCompare k => (k v -> f v -> f v -> f v) -> k v -> f v -> MonoidalDMap k f
-> (Maybe (f v), MonoidalDMap k f)
insertLookupWithKey f k v (MonoidalDMap m) =
case DMap.insertLookupWithKey f k v m of
(x, y) -> (x, MonoidalDMap y)
insertLookupWithKey' :: forall k f v. GCompare k => (k v -> f v -> f v -> f v) -> k v -> f v -> MonoidalDMap k f
-> (Maybe (f v), MonoidalDMap k f)
insertLookupWithKey' f k v (MonoidalDMap m) =
case DMap.insertLookupWithKey' f k v m of
(x, y) -> (x, MonoidalDMap y)
delete :: forall k f v. GCompare k => k v -> MonoidalDMap k f -> MonoidalDMap k f
delete k (MonoidalDMap m) = MonoidalDMap (DMap.delete k m)
adjust :: GCompare k => (f v -> f v) -> k v -> MonoidalDMap k f -> MonoidalDMap k f
adjust f k (MonoidalDMap m) = MonoidalDMap (DMap.adjust f k m)
adjustWithKey :: GCompare k => (k v -> f v -> f v) -> k v -> MonoidalDMap k f -> MonoidalDMap k f
adjustWithKey f k (MonoidalDMap m) = MonoidalDMap (DMap.adjustWithKey f k m)
adjustWithKey' :: GCompare k => (k v -> f v -> f v) -> k v -> MonoidalDMap k f -> MonoidalDMap k f
adjustWithKey' f k (MonoidalDMap m) = MonoidalDMap (DMap.adjustWithKey' f k m)
update :: GCompare k => (f v -> Maybe (f v)) -> k v -> MonoidalDMap k f -> MonoidalDMap k f
update f k (MonoidalDMap m) = MonoidalDMap (DMap.update f k m)
updateWithKey :: forall k f v. GCompare k => (k v -> f v -> Maybe (f v)) -> k v -> MonoidalDMap k f -> MonoidalDMap k f
updateWithKey f k (MonoidalDMap m) = MonoidalDMap (DMap.updateWithKey f k m)
updateLookupWithKey :: forall k f v. GCompare k => (k v -> f v -> Maybe (f v)) -> k v -> MonoidalDMap k f -> (Maybe (f v), MonoidalDMap k f)
updateLookupWithKey f k (MonoidalDMap m) =
case DMap.updateLookupWithKey f k m of
(x, y) -> (x, MonoidalDMap y)
alter :: forall k f v. GCompare k => (Maybe (f v) -> Maybe (f v)) -> k v -> MonoidalDMap k f -> MonoidalDMap k f
alter f k (MonoidalDMap m) = MonoidalDMap (DMap.alter f k m)
findIndex :: GCompare k => k v -> MonoidalDMap k f -> Int
findIndex k (MonoidalDMap m)
= case DMap.lookupIndex k m of
Nothing -> error "MonoidalDMap.findIndex: element is not in the map"
Just idx -> idx
lookupIndex :: forall k f v. GCompare k => k v -> MonoidalDMap k f -> Maybe Int
lookupIndex k (MonoidalDMap m) = DMap.lookupIndex k m
elemAt :: Int -> MonoidalDMap k f -> DSum k f
elemAt i (MonoidalDMap m) = DMap.elemAt i m
updateAt :: (forall v. k v -> f v -> Maybe (f v)) -> Int -> MonoidalDMap k f -> MonoidalDMap k f
updateAt f i (MonoidalDMap m) = MonoidalDMap (DMap.updateAt f i m)
deleteAt :: Int -> MonoidalDMap k f -> MonoidalDMap k f
deleteAt i (MonoidalDMap m) = MonoidalDMap (DMap.deleteAt i m)
findMin :: MonoidalDMap k f -> DSum k f
findMin (MonoidalDMap m) = case DMap.lookupMin m of
Just x -> x
Nothing -> error "MonoidalDMap.findMin: empty map has no minimal element"
lookupMin :: MonoidalDMap k f -> Maybe (DSum k f)
lookupMin (MonoidalDMap m) = DMap.lookupMin m
findMax :: MonoidalDMap k f -> DSum k f
findMax m = case lookupMax m of
Just x -> x
Nothing -> error "Map.findMax: empty map has no maximal element"
lookupMax :: MonoidalDMap k f -> Maybe (DSum k f)
lookupMax (MonoidalDMap m) = DMap.lookupMax m
deleteMin :: MonoidalDMap k f -> MonoidalDMap k f
deleteMin (MonoidalDMap m) = MonoidalDMap (DMap.deleteMin m)
deleteMax :: MonoidalDMap k f -> MonoidalDMap k f
deleteMax (MonoidalDMap m) = MonoidalDMap (DMap.deleteMax m)
updateMinWithKey :: (forall v. k v -> f v -> Maybe (f v)) -> MonoidalDMap k f -> MonoidalDMap k f
updateMinWithKey f (MonoidalDMap m) = MonoidalDMap (DMap.updateMinWithKey f m)
updateMaxWithKey :: (forall v. k v -> f v -> Maybe (f v)) -> MonoidalDMap k f -> MonoidalDMap k f
updateMaxWithKey f (MonoidalDMap m) = MonoidalDMap (DMap.updateMaxWithKey f m)
unionsWithKey :: GCompare k => (forall v. k v -> f v -> f v -> f v) -> [MonoidalDMap k f] -> MonoidalDMap k f
unionsWithKey f ms = MonoidalDMap (DMap.unionsWithKey f (coerce ms))
unionWithKey :: GCompare k => (forall v. k v -> f v -> f v -> f v) -> MonoidalDMap k f -> MonoidalDMap k f -> MonoidalDMap k f
unionWithKey f (MonoidalDMap m) (MonoidalDMap n) = MonoidalDMap (DMap.unionWithKey f m n)
difference :: GCompare k => MonoidalDMap k f -> MonoidalDMap k g -> MonoidalDMap k f
difference (MonoidalDMap m) (MonoidalDMap n) = MonoidalDMap (DMap.difference m n)
differenceWithKey :: GCompare k => (forall v. k v -> f v -> g v -> Maybe (f v)) -> MonoidalDMap k f -> MonoidalDMap k g -> MonoidalDMap k f
differenceWithKey f (MonoidalDMap m) (MonoidalDMap n) = MonoidalDMap (DMap.differenceWithKey f m n)
intersectionWithKey :: GCompare k => (forall v. k v -> f v -> g v -> h v) -> MonoidalDMap k f -> MonoidalDMap k g -> MonoidalDMap k h
intersectionWithKey f (MonoidalDMap m) (MonoidalDMap n) = MonoidalDMap (DMap.intersectionWithKey f m n)
isSubmapOf :: (GCompare k, Has' Eq k f) => MonoidalDMap k f -> MonoidalDMap k f -> Bool
isSubmapOf (MonoidalDMap m) (MonoidalDMap n) = DMap.isSubmapOf m n
isSubmapOfBy :: GCompare k => (forall v. k v -> k v -> f v -> g v -> Bool) -> MonoidalDMap k f -> MonoidalDMap k g -> Bool
isSubmapOfBy f (MonoidalDMap m) (MonoidalDMap n) = DMap.isSubmapOfBy f m n
isProperSubmapOf :: (GCompare k, Has' Eq k f) => MonoidalDMap k f -> MonoidalDMap k f -> Bool
isProperSubmapOf (MonoidalDMap m) (MonoidalDMap n) = DMap.isProperSubmapOf m n
isProperSubmapOfBy :: GCompare k => (forall v. k v -> k v -> f v -> g v -> Bool) -> MonoidalDMap k f -> MonoidalDMap k g -> Bool
isProperSubmapOfBy f (MonoidalDMap m) (MonoidalDMap n) = DMap.isProperSubmapOfBy f m n
filterWithKey :: GCompare k => (forall v. k v -> f v -> Bool) -> MonoidalDMap k f -> MonoidalDMap k f
filterWithKey p (MonoidalDMap m) = MonoidalDMap (DMap.filterWithKey p m)
partitionWithKey :: GCompare k => (forall v. k v -> f v -> Bool) -> MonoidalDMap k f -> (MonoidalDMap k f, MonoidalDMap k f)
partitionWithKey p (MonoidalDMap m) =
case DMap.partitionWithKey p m of
(x, y) -> (MonoidalDMap x, MonoidalDMap y)
mapMaybeWithKey :: GCompare k => (forall v. k v -> f v -> Maybe (g v)) -> MonoidalDMap k f -> MonoidalDMap k g
mapMaybeWithKey f (MonoidalDMap m) = MonoidalDMap (DMap.mapMaybeWithKey f m)
mapEitherWithKey :: GCompare k =>
(forall v. k v -> f v -> Either (g v) (h v)) -> MonoidalDMap k f -> (MonoidalDMap k g, MonoidalDMap k h)
mapEitherWithKey f (MonoidalDMap m) =
case DMap.mapEitherWithKey f m of
(x, y) -> (MonoidalDMap x, MonoidalDMap y)
map :: (forall v. f v -> g v) -> MonoidalDMap k f -> MonoidalDMap k g
map f (MonoidalDMap m) = MonoidalDMap (DMap.map f m)
mapWithKey :: (forall v. k v -> f v -> g v) -> MonoidalDMap k f -> MonoidalDMap k g
mapWithKey f (MonoidalDMap m) = MonoidalDMap (DMap.mapWithKey f m)
traverseWithKey :: Applicative t => (forall v. k v -> f v -> t (g v)) -> MonoidalDMap k f -> t (MonoidalDMap k g)
traverseWithKey f (MonoidalDMap m) = fmap MonoidalDMap (DMap.traverseWithKey f m)
mapAccumLWithKey :: (forall v. a -> k v -> f v -> (a, g v)) -> a -> MonoidalDMap k f -> (a, MonoidalDMap k g)
mapAccumLWithKey f x (MonoidalDMap m) =
case DMap.mapAccumLWithKey f x m of
(y, m') -> (y, MonoidalDMap m')
mapAccumRWithKey :: (forall v. a -> k v -> f v -> (a, g v)) -> a -> MonoidalDMap k f -> (a, MonoidalDMap k g)
mapAccumRWithKey f x (MonoidalDMap m) =
case DMap.mapAccumRWithKey f x m of
(y, m') -> (y, MonoidalDMap m')
mapKeysWith :: GCompare k2 => (forall v. k2 v -> f v -> f v -> f v) -> (forall v. k1 v -> k2 v) -> MonoidalDMap k1 f -> MonoidalDMap k2 f
mapKeysWith c f (MonoidalDMap m) = MonoidalDMap (DMap.mapKeysWith c f m)
mapKeysMonotonic :: (forall v. k1 v -> k2 v) -> MonoidalDMap k1 f -> MonoidalDMap k2 f
mapKeysMonotonic f (MonoidalDMap m) = MonoidalDMap (DMap.mapKeysMonotonic f m)
foldrWithKey :: (forall v. k v -> f v -> b -> b) -> b -> MonoidalDMap k f -> b
foldrWithKey f x (MonoidalDMap m) = DMap.foldrWithKey f x m
foldlWithKey :: (forall v. b -> k v -> f v -> b) -> b -> MonoidalDMap k f -> b
foldlWithKey f x (MonoidalDMap m) = DMap.foldlWithKey f x m
keys :: MonoidalDMap k f -> [Some k]
keys (MonoidalDMap m) = DMap.keys m
assocs :: MonoidalDMap k f -> [DSum k f]
assocs (MonoidalDMap m) = DMap.assocs m
fromListWithKey :: GCompare k => (forall v. k v -> f v -> f v -> f v) -> [DSum k f] -> MonoidalDMap k f
fromListWithKey f xs = MonoidalDMap (DMap.fromListWithKey f xs)
toList :: MonoidalDMap k f -> [DSum k f]
toList (MonoidalDMap m) = DMap.toList m
toAscList :: MonoidalDMap k f -> [DSum k f]
toAscList (MonoidalDMap m) = DMap.toAscList m
toDescList :: MonoidalDMap k f -> [DSum k f]
toDescList (MonoidalDMap m) = DMap.toDescList m
fromAscListWithKey :: GEq k => (forall v. k v -> f v -> f v -> f v) -> [DSum k f] -> MonoidalDMap k f
fromAscListWithKey f xs = MonoidalDMap (DMap.fromAscListWithKey f xs)
split :: forall k f v. GCompare k => k v -> MonoidalDMap k f -> (MonoidalDMap k f, MonoidalDMap k f)
split k (MonoidalDMap m) =
case DMap.split k m of
(x, y) -> (MonoidalDMap x, MonoidalDMap y)
{-# INLINABLE split #-}
splitLookup :: forall k f v. GCompare k => k v -> MonoidalDMap k f -> (MonoidalDMap k f, Maybe (f v), MonoidalDMap k f)
splitLookup k (MonoidalDMap m) =
case DMap.splitLookup k m of
(x, v, y) -> (MonoidalDMap x, v, MonoidalDMap y)
showTree :: (GShow k, Has' Show k f) => MonoidalDMap k f -> String
showTree (MonoidalDMap m) = DMap.showTree m
showTreeWith :: (forall v. k v -> f v -> String) -> Bool -> Bool -> MonoidalDMap k f -> String
showTreeWith showElem hang wide (MonoidalDMap m) = DMap.showTreeWith showElem hang wide m
valid :: GCompare k => MonoidalDMap k f -> Bool
valid (MonoidalDMap m) = DMap.valid m