
class Monad m => MonadIS m where getIS :: m IntState putIS :: IntState -> m () Most functions are generalized over this class. And to further improve
Hallo Yhc developers, While I was in a masochistic mood this week, I decided to change Yhc to use proper monads. The old State.hs 'monad' was based around the functions (>>>=) and (>>>), representing a WriterT State monad. They had some quirky features, like different output state types, and because of the writer monad, there were lots of functions taking dummy environment parameters. There was also a different State0 s type representing State s (). I have replaced this mess by usage of the mtl, in particular Control.Monad.State and Control.Monad.Writer. Usage of (>>>=) is replaced by do notation. As replacement for the (=>>>) operator I use (<*>) and (<$>) based on Control.Applicative. I also added a new class "MonadIS" for monads that carry IntState around. the readability, all state and environment types are now records. Now, I may have introduced some bugs. The code was rather fond of reusing variable names like
case liftExp exp state of (exp, state) -> ... While I tried to be careful, it is possible that somewhere there is a reference to an old value. Yhc does still pass the test suite.
I may have also removed some of the strictness, in the old code =>>> (aka. <*>) was strict in the state, after the cleanup it no longer is. This could be fixed by using a different monad. There is already a StrictState monad in State.hs which I used for debugging (to get traces in some sensible order). I also changed "case x of (a,b) -> y" into "let (a,b) = x" in do blocks. Usually either a or b is examined afterwards anyway, so it should not matter much for the strictness. Unfortunately, the code now requires -fglasgow-exts (or a LANGUAGE pragma) in some places. The only reason for this is FlexibleInstances for the instance:
instance MonadIS (State IntState) where ... If this is a problem it might be possible to work around it by changing it to: class HasIntState a instance HasIntState a => MonadIS (State a) But IMO FlexibleInstances are a noncontroversial extension, and they are supported by most compilers.
Finally, it should be noted that I kind of gave up at the end; the type checker just uses runState to get around the monads. The reason for this is that I saw a circular reference there somewhere, and I decided it was best not to mess with it. The patch is too big to send by email to this list, so it can be downloaded from http://twan.home.fmf.nl/yhc-mtl.patch.gz Twan van Laarhoven