{-# LANGUAGE DataKinds #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Data.Tree.BST.Utils
( Member,
LookupValueType,
)
where
import Data.Kind (Type)
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 (EQ, LT))
type family Member (x :: Nat) (t :: Tree) (t' :: Tree) :: Bool where
Member x ('ForkTree l (Node n _a) r) t' =
( If
(CmpNat x n == 'EQ)
'True
( If
(CmpNat x n == 'LT)
(Member x l t')
(Member x r t')
)
)
Member x 'EmptyTree t' = TypeError ('Text "Key " ':<>: 'ShowType x ':<>: 'Text " not found in tree " ':<>: 'ShowType t')
type family LookupValueType (x :: Nat) (t :: Tree) (t' :: Tree) :: Type where
LookupValueType x ('ForkTree l (Node n a) r) t' =
( If
(CmpNat x n == 'EQ)
a
( If
(CmpNat x n == 'LT)
(LookupValueType x l t')
(LookupValueType x r t')
)
)
LookupValueType x 'EmptyTree t' = TypeError ('Text "Key " ':<>: 'ShowType x ':<>: 'Text " not found in tree " ':<>: 'ShowType t')