packages feed

HaRe-0.6: StrategyLib-4.0-beta/examples/haskell/DoElim.hs

module DoElim (doElim) where

-------------------------------------------------------------------------------

--- This module implements a transformation that implements de-sugaring
--- of Haskell's "do" notation

-------------------------------------------------------------------------------

import Language.Haskell.Syntax
import SyntaxTermInstances
import StrategyLib
import Monad

-- Elimination of do notation -------------------------------------------------

doElim 	   :: (Term a, MonadPlus m) => a -> m a
doElim h   =  applyTP (innermost (monoTP doElim1)) h

doElim1    :: MonadPlus m => HsExp -> m HsExp
doElim1 (HsDo [HsQualifier e]) 	
  = return e
doElim1 (HsDo (HsQualifier e:stmts))	
  = return (HsInfixApp e (HsQVarOp (hsSymbol ">>")) (HsDo stmts))
doElim1 (HsDo (HsGenerator _ p e:stmts))
  = do ok <- new_name
       return (letPattern ok p e stmts)
doElim1 (HsDo (HsLetStmt decls:stmts))
  = return (HsLet decls (HsDo stmts))
doElim1 _                      
  = mzero

-- Auxiliaries ----------------------------------------------------------------

letPattern ok p e stmts
  = let fail    = hsIdent "fail"        
        failmsg = "Error: pattern-match failure in do-expression."
        mthen   = HsQVarOp (hsSymbol ">>=")
    in (HsLet [HsFunBind [HsMatch noSrcLoc (HsIdent ok) [p] (HsUnGuardedRhs (HsDo stmts)) []],HsFunBind [HsMatch noSrcLoc (HsIdent ok) [HsPWildCard] (HsUnGuardedRhs (HsApp (HsVar fail) (HsLit (HsString failmsg)))) []]] (HsInfixApp e mthen (HsVar (hsIdent ok))))

noSrcLoc = SrcLoc "" 0 0 

hsSymbol s = (UnQual (HsSymbol s))
hsIdent s  = (UnQual (HsIdent s))

new_name :: Monad m => m String
new_name = return "ok"

-- Test terms -----------------------------------------------------------------

do1
  = let silly  = HsIdent "silly"
        aap    = hsIdent "aap"
        aap'   = HsIdent "aap"
        noot   = hsIdent "noot"
        noot'  = HsIdent "noot"
        return = hsIdent "return" 
        bind   = hsSymbol ">>="
    in HsModule noSrcLoc (Module "Do1") Nothing [] [HsFunBind [HsMatch (SrcLoc "" 3 12) silly [HsPVar noot'] (HsUnGuardedRhs (HsDo [HsGenerator noSrcLoc (HsPVar aap') (HsVar noot),HsQualifier (HsApp (HsVar return) (HsVar aap))])) []]]

nodo1 
  = let silly  = HsIdent "silly"
        aap    = hsIdent "aap"
        aap'   = HsIdent "aap"
        noot   = hsIdent "noot"
        noot'  = HsIdent "noot"
        return = hsIdent "return" 
        bind   = hsSymbol ">>="
    in HsModule noSrcLoc (Module "Do1") Nothing [] [HsFunBind [HsMatch (SrcLoc "" 3 12) silly [HsPVar noot'] (HsUnGuardedRhs (HsInfixApp (HsVar noot) (HsQVarOp bind) (HsLambda noSrcLoc [HsPVar aap'] (HsApp (HsVar return) (HsVar aap))))) []]]

-------------------------------------------------------------------------------