module Data.Chatty.Focus (Focus, focusSelect) where
import Data.Chatty.BST
import Data.Chatty.None
newtype Focus a = Focus { runFocus :: BST a }
instance None (Focus a) where
none = Focus none
instance Indexable i o v => AnyBST Focus i o v where
anyBstInsert i t = Focus $ bstInsert i $ runFocus t
anyBstRemove o t = Focus $ bstRemove o $ runFocus t
anyBstMax t = bstMax $ runFocus t
anyBstMin t = bstMin $ runFocus t
anyBstLookup o t = bstLookup o $ runFocus t
anyBstHead t = bstHead $ runFocus t
anyBstEmpty = Focus none
anyBstInorder t = bstInorder $ runFocus t
focusSelect' :: Indexable i o v => o -> BST i -> Maybe (BST i)
focusSelect' _ EmptyBST = Nothing
focusSelect' o t@(BST a l r)
| o == indexOf a = Just t
| o < indexOf a = case focusSelect' o l of
Just (BST a' l' r') -> Just $ BST a' l' (BST a r' r)
Nothing -> Nothing
| otherwise = case focusSelect' o r of
Nothing -> Nothing
Just (BST a' l' r') -> Just $ BST a' (BST a l l') r'
focusInsert' :: Indexable i o v => i -> BST i -> BST i
focusInsert' i = unjust . focusSelect' (indexOf i) . bstInsert i
where unjust (Just j) = j
focusSelect o t = fmap Focus $ focusSelect' o $ runFocus t