summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikolaj Konarski <mikolaj.konarski@funktory.com>2025-05-10 19:12:29 +0200
committerMikolaj Konarski <mikolaj.konarski@funktory.com>2025-05-10 19:12:29 +0200
commit0339605a9a55ab49694f246f5cc3376699a80674 (patch)
treeb7f70228292e9af362f362b200cb2e24feaf349a
parent66930fd97543746bfa9a74635985ec765bd3c2e0 (diff)
Implement Min\/Max ops
-rw-r--r--src/Data/Dependent/EnumMap/Strict/Internal.hs66
1 files changed, 50 insertions, 16 deletions
diff --git a/src/Data/Dependent/EnumMap/Strict/Internal.hs b/src/Data/Dependent/EnumMap/Strict/Internal.hs
index 2726a50..c93b821 100644
--- a/src/Data/Dependent/EnumMap/Strict/Internal.hs
+++ b/src/Data/Dependent/EnumMap/Strict/Internal.hs
@@ -77,6 +77,7 @@ singleton k v =
let (i, inf) = fromEnum1 k
in DEnumMap (IM.singleton i (KV inf v))
+-- TODO: probably doesn't make much sense until we have DEnumSet? Or should we ust lists instead?
-- fromSet
-- ** From Unordered Lists
@@ -292,7 +293,7 @@ unionWithKey f (DEnumMap m1 :: DEnumMap k v) (DEnumMap m2) = DEnumMap (IM.unionW
f' :: Int -> KV k v -> KV k v -> KV k v
f' i (KV inf1 v1) (KV inf2 v2) = case toEnum1 i inf1 of
Some k1 -> typeCheck1 k1 i inf2 $ KV inf1 (f k1 (coe1 v1) (coe1 v2))
- -- TODO: are the coe1 correct? is the use of typeCheck1 fine?
+ -- TODO: are the coe1 correct? is the typeCheck1 needed?
unions :: (Foldable f, Enum1 k, TestEquality k) => f (DEnumMap k v) -> DEnumMap k v
unions xs = Foldable.foldl' union empty xs
@@ -409,6 +410,7 @@ mapAccumRWithKey f acc0 (DEnumMap m) =
-- * Folds
+-- TODO: did I miss any typeCheck1 or typeCheck2 here or anywhere else? Or are any checks spurious?
foldr :: (forall a. v a -> acc -> acc) -> acc -> DEnumMap k v -> acc
foldr f acc0 (DEnumMap m) = IM.foldr (\(KV _ v) acc -> f v acc) acc0 m
@@ -527,6 +529,7 @@ split k (DEnumMap m) = bimap DEnumMap DEnumMap (IM.split (fst $ fromEnum1 k) m)
-- TODO: is this coe1 fine or can we readably check that IM doesn't cheat
-- and give us a value with a wrong type?
+-- Or Maybe we should return @Some v@ instead of @v a@? But it has to match @k a@, right?
splitLookup :: Enum1 k => k a -> DEnumMap k v -> (DEnumMap k v, Maybe (v a), DEnumMap k v)
splitLookup k (DEnumMap m) =
let (m1, mkv, m2) = IM.splitLookup (fst $ fromEnum1 k) m
@@ -542,21 +545,52 @@ splitRoot (DEnumMap m) = DEnumMap <$> IM.splitRoot m
-- * Min\/Max
--- lookupMin
--- lookupMax
--- findMin
--- findMax
--- deleteMin
--- deleteMax
--- deleteFindMin
--- deleteFindMax
--- updateMin
--- updateMax
--- updateMinWithKey
--- updateMaxWithKey
--- minView
--- maxView
--- minViewWithKey
+lookupMin :: Enum1 k => DEnumMap k v -> Maybe (DSum k v)
+lookupMin (DEnumMap m) = kVToDSum <$> IM.lookupMin m
+
+lookupMax :: Enum1 k => DEnumMap k v -> Maybe (DSum k v)
+lookupMax (DEnumMap m) = kVToDSum <$> IM.lookupMax m
+
+findMin :: Enum1 k => DEnumMap k v -> DSum k v
+findMin (DEnumMap m) = kVToDSum $ IM.findMin m
+
+findMax :: Enum1 k => DEnumMap k v -> DSum k v
+findMax (DEnumMap m) = kVToDSum $ IM.findMax m
+
+deleteMin :: DEnumMap k v -> DEnumMap k v
+deleteMin (DEnumMap m) = DEnumMap $ IM.deleteMin m
+
+deleteMax :: DEnumMap k v -> DEnumMap k v
+deleteMax (DEnumMap m) = DEnumMap $ IM.deleteMax m
+
+deleteFindMin :: Enum1 k => DEnumMap k v -> (DSum k v, DEnumMap k v)
+deleteFindMin (DEnumMap m) = bimap kVToDSum DEnumMap $ IM.deleteFindMin m
+
+deleteFindMax :: Enum1 k => DEnumMap k v -> (DSum k v, DEnumMap k v)
+deleteFindMax (DEnumMap m) = bimap kVToDSum DEnumMap $ IM.deleteFindMax m
+
+updateMin :: forall c (k :: c -> Type) (v :: c -> Type). Enum1 k => (forall a. v a -> Maybe (v a)) -> DEnumMap k v -> DEnumMap k v
+updateMin f = updateMinWithKey (\_ x -> f x)
+
+updateMinWithKey :: Enum1 k => (forall a. k a -> v a -> Maybe (v a)) -> DEnumMap k v -> DEnumMap k v
+updateMinWithKey f (DEnumMap m) =
+ DEnumMap (IM.updateMinWithKey (\i (KV inf v) -> case toEnum1 i inf of Some k -> KV inf <$> f k (coe1 v)) m)
+
+updateMax :: forall c (k :: c -> Type) (v :: c -> Type). Enum1 k => (forall a. v a -> Maybe (v a)) -> DEnumMap k v -> DEnumMap k v
+updateMax f = updateMaxWithKey (\_ x -> f x)
+
+updateMaxWithKey :: Enum1 k => (forall a. k a -> v a -> Maybe (v a)) -> DEnumMap k v -> DEnumMap k v
+updateMaxWithKey f (DEnumMap m) =
+ DEnumMap (IM.updateMaxWithKey (\i (KV inf v) -> case toEnum1 i inf of Some k -> KV inf <$> f k (coe1 v)) m)
+
+minView :: DEnumMap k v -> Maybe (v a, DEnumMap k v)
+minView (DEnumMap m) = bimap (\(KV _ v) -> coe1 v) DEnumMap <$> IM.minView m
+
+maxView :: DEnumMap k v -> Maybe (v a, DEnumMap k v)
+maxView (DEnumMap m) = bimap (\(KV _ v) -> coe1 v) DEnumMap <$> IM.maxView m
+
+minViewWithKey :: Enum1 k => DEnumMap k v -> Maybe (DSum k v, DEnumMap k v)
+minViewWithKey (DEnumMap m) = bimap kVToDSum DEnumMap <$> IM.minViewWithKey m
maxViewWithKey :: Enum1 k => DEnumMap k v -> Maybe (DSum k v, DEnumMap k v)
maxViewWithKey (DEnumMap m) = bimap kVToDSum DEnumMap <$> IM.maxViewWithKey m