module Overload.Normal where
import Control.Effects.State
import Data.Functor.Identity
import Overload.TypeTree
newtype Normal = Normal Int deriving (Eq, Ord)
instance Show Normal where
show (Normal n) = show n
type FreshSource a = ([(a, Normal)], Normal)
lookupName :: (MonadEffect (State (FreshSource a)) m, Eq a) => a -> m Normal
lookupName name = do
(table, Normal top) <- getState
case lookup name table of
Nothing -> do
setState ((name, Normal top) : table, Normal (top + 1))
return (Normal top)
Just n -> return n
freshVar :: forall a m. MonadEffect (State (FreshSource a)) m => m Normal
freshVar = do
(table, Normal top) :: FreshSource a <- getState
setState (table, Normal (top + 1))
return (Normal top)
normalizeTypeTree :: forall a. Eq a => TypeTree (Maybe a) -> TypeTree Normal
normalizeTypeTree =
runIdentity
. implementStateViaStateT (([], Normal 0) :: FreshSource a)
. traverse (maybe (freshVar @a) lookupName)