Splitting MonadTrav, revisited

Aaron Tomb aarontomb at gmail.com
Wed Jul 22 21:42:12 EDT 2009


A while back, I brought up the fact that MonadTrav really serves  
several purposes, each of which would ideally be described by a  
separate class. I advocated creating one class for name generation,  
one for symbol table handling, and one for the rest of what's  
currently in MonadTrav.

If these are entirely separate classes, then existing code in the  
MonadTrav monad would need additional class constraints. However, if  
MonadTrav is a subclass of the other two, most code will work  
unchanged. Only instance declarations will need any modification (and  
the modifications they would need are totally mechanical). The new  
class structure would be like this:

class (Monad m) => MonadName m where
     -- | unique name generation
     genName :: m Name

class (Monad m) => MonadSymtab m where
     -- symbol table handling
     -- | return the definition table
     getDefTable :: m DefTable
     -- | perform an action modifying the definition table
     withDefTable :: (DefTable -> (a, DefTable)) -> m a

-- | Traversal monad
class (MonadName m, MonadSymtab m) => MonadTrav m where
     -- error handling facilities

     -- | throw an 'Error'
     throwTravError :: Error e => e -> m a
     -- | catch an 'Error' (we could implement dynamically-typed catch  
     catchTravError :: m a -> (CError -> m a) -> m a
     -- | remember that an 'Error' occured (without throwing it)
     recordError    :: Error e => e -> m ()
     -- | return the list of recorded errors
     getErrors      :: m [CError]

     -- | handling declarations and definitions
     handleDecl :: DeclEvent -> m ()

I have a patch that makes this change. It compiles cleanly (and, of  
course, passes all tests, since it's just a type change).

Are there any objections to me pushing it into the repository?


More information about the Language-c mailing list