Splitting MonadTrav, revisited
Aaron Tomb
aarontomb at gmail.com
Wed Jul 22 21:42:12 EDT 2009
Hello,
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
here)
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?
Aaron
More information about the Language-c
mailing list