data Color = Blk | Red
data Tree a = Empty | Node Color (Tree a) a (Tree a)
show (Node Blk nl n nr
) = "(" ++ show nl
++ " " ++ show n
++ " " ++ show nr
++ ")" show (Node Red nl n nr
) = "{" ++ show nl
++ " " ++ show n
++ " " ++ show nr
++ "}"
insert
:: Ord a
=> a
-> Tree a
-> Tree a
insert x y = let (Node _ nl n nr) = insert' x y in Node Blk nl n nr
insert' :: Ord a
=> a
-> Tree a
-> Tree a
insert' x Empty = Node Red Empty x Empty
insert' x y
@(Node col nl n nr
) = case compare x n
of LT -> fix (Node col (insert' x nl) n nr)
GT -> fix (Node col nl n (insert' x nr))
EQ -> y
-- This function has nothing to do with fixed points :)
-- It fixes intermediate trees to maintain the invariants.
fix :: Tree a -> Tree a
-- red left left with red uncle
fix (Node Blk (Node Red nn@(Node Red _ _ _) p pr) g (Node Red ul u ur)) =
Node Red (Node Blk nn p pr) g (Node Blk ul u ur)
-- red right left with red uncle
fix (Node Blk (Node Red ul u ur) g (Node Red nn@(Node Red _ _ _) p pr)) =
Node Red (Node Blk ul u ur) g (Node Blk nn p pr)
-- red left right with red uncle
fix (Node Blk (Node Red pl p nn@(Node Red _ _ _)) g (Node Red ul u ur)) =
Node Red (Node Blk pl p nn ) g (Node Blk ul u ur)
-- red right right with red uncle
fix (Node Blk (Node Red ul u ur) g (Node Red pl p nn@(Node Red _ _ _))) =
Node Red (Node Blk ul u ur) g (Node Blk pl p nn )
-- red left left with black uncle
fix (Node Blk (Node Red nn@(Node Red _ _ _) p pr) g uu) =
Node Blk nn p (Node Red pr g uu)
-- red right right with black uncle
fix (Node Blk uu g (Node Red pl p nn@(Node Red _ _ _))) =
Node Blk (Node Red uu g pl) p nn
-- red left right with black uncle
fix (Node Blk (Node Red pl p (Node Red nl n nr)) g uu) =
Node Blk (Node Red pl p nl) n (Node Red nr g uu)
-- red right left with black uncle
fix (Node Blk uu g (Node Red (Node Red nl n nr) p pr)) =
Node Blk (Node Red uu g nl) n (Node Red nr p pr)
fix t = t
test = [89,32,31,65,20,94,25,45,60,39,60,64,99,69,33]