implementation module pprint import Control.Applicative import Control.Monad => qualified join import Control.Monad.Reader import Control.Monad.Identity import Data.Func import Data.Functor import Data.List import Text import StdEnv import test :: DSL | PPrintVar String pprint :: DSL -> String pprint d = concat $ runReader (print d) ["x" +++ toString i\\i<-[0..]] print :: DSL -> Reader [String] [String] print (Lit i) = pure $ pure $ toString i print (PPrintVar s) = pure $ pure s print (Var def) = asks hd >>= \v-> let (i In d) = def (PPrintVar v) in local tl $ ((++) ["var ",v,"=",toString i," in\n"]) <$> print d print (a +. b) = liftA2 (\as bs->as++["+":bs]) (print a) (print b)