{-# LANGUAGE DataKinds, TypeOperators, ConstraintKinds, PolyKinds, TypeFamilies, GADTs, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, FlexibleContexts, UndecidableInstances, UndecidableSuperClasses, TypeApplications, ScopedTypeVariables, AllowAmbiguousTypes, ExplicitForAll, RankNTypes, DefaultSignatures, PartialTypeSignatures, LambdaCase, EmptyCase #-} {-# OPTIONS_GHC -Wno-partial-type-signatures #-} module Data.RBR.Demoted where import Data.RBR.Internal import Data.Proxy import Data.Kind import Data.Typeable import GHC.TypeLits emptyMap :: Map String TypeRep emptyMap = E class DemotableColor (c :: Color) where demoteColor :: Proxy c -> Color instance DemotableColor R where demoteColor _ = R instance DemotableColor B where demoteColor _ = B class DemotableMap (t :: Map Symbol Type) where demoteMap :: Proxy t -> Map String TypeRep instance DemotableMap E where demoteMap _ = E instance (DemotableColor c, KnownSymbol s, Typeable ty, DemotableMap l, DemotableMap r) => DemotableMap (N c l s ty r) where demoteMap _ = N (demoteColor (Proxy @c)) (demoteMap (Proxy @l)) (symbolVal (Proxy @s)) (typeRep (Proxy @ty)) (demoteMap (Proxy @r)) t_insert :: Ord a => a -> v -> Map a v -> Map a v t_insert x val s = N B a v z b where N _ a v z b = ins s ins E = N R E x val E ins s@(N B a y val' b) | xy = t_balance a y val' (ins b) | otherwise = s ins s@(N R a y val' b) | xy = N R a y val' (ins b) | otherwise = s t_balance :: Map a v -> a -> v -> Map a v -> Map a v t_balance (N R a x xv b) y yv (N R c z zv d) = N R (N B a x xv b) y yv (N B c z zv d) t_balance (N R (N R a x xv b) y yv c) z zv d = N R (N B a x xv b) y yv (N B c z zv d) t_balance (N R a x xv (N R b y yv c)) z zv d = N R (N B a x xv b) y yv (N B c z zv d) t_balance a x xv (N R b y yv (N R c z zv d)) = N R (N B a x xv b) y yv (N B c z zv d) t_balance a x xv (N R (N R b y yv c) z zv d) = N R (N B a x xv b) y yv (N B c z zv d) t_balance a x xv b = N B a x xv b t_delete :: Ord a => a -> Map a v -> Map a v t_delete x t = case del t of {N _ a y yv b -> N B a y yv b; _ -> E} where del E = E del (N _ a y yv b) | xy = delformRight a y yv b | otherwise = t_app a b delformLeft a@(N B _ _ _ _) y yv b = t_balleft (del a) y yv b delformLeft a y yv b = N R (del a) y yv b delformRight a y yv b@(N B _ _ _ _) = t_balright a y yv (del b) delformRight a y yv b = N R a y yv (del b) t_balleft :: Map a v -> a -> v -> Map a v -> Map a v t_balleft (N R a x xv b) y yv c = N R (N B a x xv b) y yv c t_balleft bl x xv (N B a y yv b) = t_balance bl x xv (N R a y yv b) t_balleft bl x xv (N R (N B a y yv b) z zv c) = N R (N B bl x xv a) y yv (t_balance b z zv (t_sub1 c)) t_balright :: Map a v -> a -> v -> Map a v -> Map a v t_balright a x xv (N R b y yv c) = N R a x xv (N B b y yv c) t_balright (N B a x xv b) y yv bl = t_balance (N R a x xv b) y yv bl t_balright (N R a x xv (N B b y yv c)) z zv bl = N R (t_balance (t_sub1 a) x xv b) y yv (N B c z zv bl) t_sub1 :: Map a v -> Map a v t_sub1 (N B a x xv b) = N R a x xv b t_sub1 _ = error "invariance violation" t_app :: Map a v -> Map a v -> Map a v t_app E x = x t_app x E = x t_app (N R a x xv b) (N R c y yv d) = case t_app b c of N R b' z zv c' -> N R (N R a x xv b') z zv (N R c' y yv d) bc -> N R a x xv (N R bc y yv d) t_app (N B a x xv b) (N B c y yv d) = case t_app b c of N R b' z zv c' -> N R (N B a x xv b') z zv (N B c' y yv d) bc -> t_balleft a x xv (N B bc y yv d) t_app a (N R b x xv c) = N R (t_app a b) x xv c t_app (N R a x xv b) c = N R a x xv (t_app b c) -- The original term-level code, taken from: -- https://www.cs.kent.ac.uk/people/staff/smk/redblack/rb.html -- -- {- Version 1, 'untyped' -} -- data Color = R | B deriving Show -- data RB a = E | T Color (RB a) a (RB a) deriving Show -- -- {- Insertion and membership test as by Okasaki -} -- insert :: Ord a => a -> RB a -> RB a -- insert x s = -- T B a z b -- where -- T _ a z b = ins s -- ins E = T R E x E -- ins s@(T B a y b) -- | xy = balance a y (ins b) -- | otherwise = s -- ins s@(T R a y b) -- | xy = T R a y (ins b) -- | otherwise = s -- -- -- {- balance: first equation is new, -- to make it work with a weaker invariant -} -- balance :: RB a -> a -> RB a -> RB a -- balance (T R a x b) y (T R c z d) = T R (T B a x b) y (T B c z d) -- balance (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d) -- balance (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d) -- balance a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d) -- balance a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d) -- balance a x b = T B a x b -- -- member :: Ord a => a -> RB a -> Bool -- member x E = False -- member x (T _ a y b) -- | xy = member x b -- | otherwise = True -- -- {- deletion a la SMK -} -- delete :: Ord a => a -> RB a -> RB a -- delete x t = -- case del t of {T _ a y b -> T B a y b; _ -> E} -- where -- del E = E -- del (T _ a y b) -- | xy = delformRight a y b -- | otherwise = app a b -- delformLeft a@(T B _ _ _) y b = balleft (del a) y b -- delformLeft a y b = T R (del a) y b -- -- delformRight a y b@(T B _ _ _) = balright a y (del b) -- delformRight a y b = T R a y (del b) -- -- balleft :: RB a -> a -> RB a -> RB a -- balleft (T R a x b) y c = T R (T B a x b) y c -- balleft bl x (T B a y b) = balance bl x (T R a y b) -- balleft bl x (T R (T B a y b) z c) = T R (T B bl x a) y (balance b z (sub1 c)) -- -- balright :: RB a -> a -> RB a -> RB a -- balright a x (T R b y c) = T R a x (T B b y c) -- balright (T B a x b) y bl = balance (T R a x b) y bl -- balright (T R a x (T B b y c)) z bl = T R (balance (sub1 a) x b) y (T B c z bl) -- -- sub1 :: RB a -> RB a -- sub1 (T B a x b) = T R a x b -- sub1 _ = error "invariance violation" -- -- app :: RB a -> RB a -> RB a -- app E x = x -- app x E = x -- app (T R a x b) (T R c y d) = -- case app b c of -- T R b' z c' -> T R(T R a x b') z (T R c' y d) -- bc -> T R a x (T R bc y d) -- app (T B a x b) (T B c y d) = -- case app b c of -- T R b' z c' -> T R(T B a x b') z (T B c' y d) -- bc -> balleft a x (T B bc y d) -- app a (T R b x c) = T R (app a b) x c -- app (T R a x b) c = T R a x (app b c)