{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE LambdaCase #-}
module RSolve.MapLike where
import Data.Maybe
import Data.Kind
import Prelude hiding (lookup, insert)
import qualified Data.Map as M
import qualified Data.List as L
import qualified Data.Set as S
class MapLike m k v | m -> k, m -> v where
lookup :: k -> m -> Maybe v
(!) :: m -> k -> v
m ! k = fromJust (lookup k m)
insert :: k -> v -> m -> m
adjust :: (v -> v) -> k -> m -> m
member :: k -> m -> Bool
update :: (v -> Maybe v) -> k -> m -> m
instance Ord k => MapLike (M.Map k v) k v where
lookup = M.lookup
(!) = (M.!)
insert = M.insert
adjust = M.adjust
member = M.member
update = M.update
instance Eq k => MapLike [(k, v)] k v where
lookup = L.lookup
insert k v = \case
[] -> [(k, v)]
(k', v'):xs | k' == k -> (k, v):xs
x:xs -> x:insert k v xs
adjust f k = \case
[] -> []
(k', v):xs | k' == k -> (k', f v):xs
x:xs -> x:adjust f k xs
k `member` m = case lookup k m of
Just _ -> True
Nothing -> False
update f k = \case
[] -> []
hd@(k', v):xs | k == k' ->
case f v of
Just v' -> (k, v'):tl
Nothing -> hd:tl
where tl = update f k xs