TiE.hs

-- Refactored type inference for the E structure.
-- Returns types and translated expressions.
module TiE where
import HasBaseStruct
import BaseSyntaxStruct
import SrcLoc
import TI
import TiLit(tcLit)
import TiFields
import TiRhs
--import TiPrelude
import MUtils
import Monad(join)--,liftM2

instance HasId i (EI i e p ds t c) where
  ident = HsId
  isId (HsId x) = Just x
  isId _ = Nothing

instance (HasBaseStruct e (EI i e p ds t c),HasId i p) => HasAbstr i (EI i e p ds t c) where
  abstract xs e = HsLambda (map var xs) (base e)

When inferring the type of an expression, we return a type and a transformed expression, which can be of any (extended) expression type, hence the requirement HasCoreSyntax e, HasBaseStruct e ... and the result type Typed e.

{-
-- Copied from the type inferred for tcE by GHC:
instance (Fresh i,TypeId i,ValueId i,
	  HasSrcLoc i, -- for error reporting
	  HasBaseStruct rec (EI i e x r t1 c1),
	  HasTypeAnnot i e,HasTypeAnnot i x,
	  TypeCheck i p1 (Typed i x),
	  TypeCheck i e1 (Typed i e),
	  TypeCheckDecls i ds r,
	  HasBaseStruct e1 (EI i e1 p1 ds t2 c2), HasId i p1, HasAbstr i e1,
	  HasBaseStruct p1 (PI i p), HasCoreSyntax i e1, HasTypeApp i rec,
	  HasLit rec,HasTypeAnnot i rec,
	  DefinedNames i p1, TypeCheck i e1 (Typed i rec),
	  HasBaseStruct d1 (DI i e1 p2 ds1 t c tp),
	  HasId i p2, HasDef ds1 d, HasDef ds d1)
 => TypeCheck i (EI i e1 p1 ds t c) (Typed i rec)
  where tc = tcE
-}
tcE e =
  case e of
    HsId n                 -> inst_loc n
    HsLit s l              -> tcLit (hsLit s) s l
    HsInfixApp x op z      -> inst_loc op `tapp` tc x `tapp` tc z
    HsApp x y              -> tc x `tapp` tc y
    HsNegApp s x           -> instPrel_srcloc s "negate" `tapp` tc x
    HsLambda ps e          -> tcLambda ps e
    HsLet ds e             -> tcLet ds (tc e)
    HsIf x y z             -> join $ tcIf # tc x <# tc y <# tc z
    HsCase e alts          -> tcCase e alts
    HsDo stmts             -> tcStmts stmts
    HsTuple es             -> typedTuple =<< mapM tc es
    HsList es              -> tcList =<< mapM tc es
    HsParen e              -> emap hsParen # tc e
    HsLeftSection x op     -> inst_loc op `tapp` tc x
    HsRightSection op y    -> instPrel "flip" `tapp` inst_loc op `tapp` tc y
    HsRecConstr s c fields -> tcFieldsCon s c fields
    HsRecUpdate s e upds   -> tcFieldsUpd s (tc e) upds
    HsEnumFrom x           -> instPrel "enumFrom" `tapp` tc x
    HsEnumFromTo x y       -> instPrel "enumFromTo" `tapp` tc x `tapp` tc y
    HsEnumFromThen x y     -> instPrel "enumFromThen" `tapp` tc x `tapp` tc y
    HsEnumFromThenTo x y z ->
      instPrel "enumFromThenTo" `tapp` tc x `tapp` tc y `tapp` tc z
    HsListComp stmts       -> emap hsListComp # tcLComp stmts
    HsExpTypeSig s e c t    -> tcExpTypeSig s e c t
    _ -> fail "Bug: not implemented yet"

tcLambda ps e =
  do (ps',e'):>:(tps,t') <- tcLambda' ps e
     let tps' = zipWith typeAnnot ps' tps
     hsLambda tps' (typeAnnot e' t') >: foldr hsTyFun t' tps

tcLambda' ps e =
  do bs <- schintro (patternVars ps)
     extendts bs $ do ps':>:tps <- unzipTyped # mapM tc ps
                      e':>:t'   <- tc e
                      (ps', e') >: (tps,t')

tcDsLambda' ps ds e =
  do bs <- schintro (patternVars ps)
     extendts bs $ do ps':>:tps <- unzipTyped # mapM tc ps
                      ds':>:dbs <- tcLocalDecls ds
                      e':>:t'   <- extendts dbs (tc e)
		      --let ds'' = addDeclsType ([],bs) ds'
                      (ps', ds', e') >: foldr hsTyFun t' tps

tcLet ds tce =
  do ds':>: bs <- tcLocalDecls ds
     e' :>: t' <- extendts bs tce
     hsLet ds' e' >: t'

tcExpTypeSig s e c t =
 do v <- fresh
    tc (hsLet (hsTypeSig s [v] c t `consDef`
	       (hsPatBind s (var v) (HsBody e) noDef `consDef` noDef))
	      (var v)  `asTypeOf` e)
    
--tcIf :: HasBaseStruct e (E e p ds t c) => Typed e -> Typed e -> Typed e -> TI (Typed e)
tcIf (cnd:>:tcnd) (thn:>:tthn) (els:>:tels) =
  do tBool <- getBoolType
     tcnd=:=tBool
     tthn=:=tels
     hsIf cnd thn els >:: tthn

tcCase e alts =
  do e':>:te <- tc e
     alts':>:ats <- unzipTyped # mapM tcAlt alts
     let (tps,tes) = unzip ats
     mapM_ (te=:=) tps
     t <- allSame tes
     hsCase e' alts' >:: t

e >:: t = typeAnnot e t >: t

tcAlt (HsAlt s p rhs ds) = 
  do bs <- schintro (patternVars p)
     extendts bs $ do p':>:tp <- tc p
	              ds':>:dbs <- tcLocalDecls ds
	              rhs':>:trhs <- extendts dbs (tc rhs)
		      --let ds'' = addDeclsType ([],bs) ds'
                      HsAlt s p' rhs' ds'>:(tp,trhs)
     
tcStmts stmts =
  do bind <- ident # prelValue ">>="
     thn <- ident # prelValue ">>"
     fail <- ident # prelValue "fail"
     let desugar stmt =
	   case stmt of
	     HsGenerator _ p e stmt -> app (bind `app` e) # match p stmt
	     HsQualifier   e stmt -> app (thn `app` e) # desugar stmt
	     HsLetStmt    ds stmt -> hsLet ds # desugar stmt
	     HsLast        e      -> return e
	 match p stmt =
	   do stmt' <- desugar stmt
	      case isVar p of
		Just v -> return $ abstract [v] stmt'
		_ -> do v <- fresh
			return (abstract [v] $
				 hsCase (var v) [p -+> stmt',
						 hsPWildCard -+> hsFailInDo])
	 hsFailInDo =
           fail `app` hsLit loc0 (HsString "pattern match failure in do")
	 p -+> e = HsAlt loc0 p (HsBody e) noDef
     tc =<< desugar stmts

tcLComp lc =
  case lc of
    HsGenerator s p e lc -> do e':>:et <- tc e
			       bs <- schintro (patternVars p)
			       let ext = extendts bs
			       p':>:pt <- ext (tc p)
			       listType <- getListType
			       et=:=listType pt
			       emap (HsGenerator s p' e') # ext (tcLComp lc)
    HsQualifier e   lc -> do e':>:t <- tc e
			     tBool <- getBoolType
			     t=:=tBool
			     emap (HsQualifier e') # tcLComp lc
    HsLetStmt    ds lc -> do ds':>: bs <- tcLocalDecls ds
			     emap (HsLetStmt ds') # extendts bs (tcLComp lc)
    HsLast      e      -> do e':>:t <- tc e
			     listType <- getListType
		             HsLast e' >: listType t

Plain-text version of TiE.hs | Valid HTML?