{-# LANGUAGE DataKinds #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Tree.BST.Invariants
( LtN,
GtN,
)
where
import Data.Tree.ITree (Tree (EmptyTree, ForkTree))
import Data.Tree.Node (Node)
import Data.Type.Bool (If)
import Data.Type.Equality (type (==))
import GHC.TypeLits (ErrorMessage (ShowType, Text, (:<>:)), TypeError)
import GHC.TypeNats (CmpNat, Nat)
import Prelude (Bool (True), Ordering (GT, LT))
type family LtN (l :: Tree) (x :: Nat) :: Bool where
LtN 'EmptyTree _x = 'True
LtN ('ForkTree l (Node n _a) r) x =
( If
(CmpNat n x == 'LT)
( If
(LtN l x)
( If
(LtN r x)
'True
(TypeError ('Text "Key " ':<>: 'ShowType x ':<>: 'Text " is not strictly lesser than keys in tree " ':<>: 'ShowType r))
)
(TypeError ('Text "Key " ':<>: 'ShowType x ':<>: 'Text " is not strictly lesser than keys in tree " ':<>: 'ShowType l))
)
(TypeError ('Text "Key " ':<>: 'ShowType x ':<>: 'Text " is not lesser than key " ':<>: 'ShowType n))
)
type family GtN (r :: Tree) (x :: Nat) :: Bool where
GtN 'EmptyTree _x = 'True
GtN ('ForkTree l (Node n _a) r) x =
( If
(CmpNat n x == 'GT)
( If
(GtN l x)
( If
(GtN r x)
'True
(TypeError ('Text "Key " ':<>: 'ShowType x ':<>: 'Text " is not strictly greater than keys in tree " ':<>: 'ShowType r))
)
(TypeError ('Text "Key " ':<>: 'ShowType x ':<>: 'Text " is not strictly greater than keys in tree " ':<>: 'ShowType l))
)
(TypeError ('Text "Key " ':<>: 'ShowType x ':<>: 'Text " is not greater than key " ':<>: 'ShowType n))
)