Subversion

Galculator

?curdirlinks? - Rev 7

?prevdifflink? - Blame



{-# LANGUAGE GADTs, FlexibleContexts #-}
{-# OPTIONS_GHC -Wall #-}
 
-------------------------------------------------------------------------------

{- |
Module      :  Language.R.TypeInference
Description :  Type inference for the expression representation.
Copyright   :  (c) Paulo Silva
License     :  LGPL
 
Maintainer  :  paufil@di.uminho.pt
Stability   :  experimental
Portability :  portable
 
-}


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

module Language.R.TypeInference (
   infer,
   inferBin,
   catchInfer,
   InfEnv
 ) where

import Control.GalcError
import Control.Monad.Error
import Control.Monad.Fresh
import Control.Monad.State
import Data.Env
import Data.Existential
import Data.List
import qualified Data.Map as Map
import Language.R.SafeCast
import Language.R.Syntax
import Language.R.SyntaxADT
import Language.Type.Constraint
import Language.Type.Syntax
import Language.Type.Unification

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

infer :: (MonadError GalcError m, MonadFresh [String] String m) --, MonadOr m)  
      => S -> m RType
infer s = evalStateT (infer' s) emptyEnv

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

type InfEnv = Env TypeBox

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

catchInfer :: (Show s, MonadError GalcError m) => s -> m a -> m a
catchInfer a f = f `catchError` (\e -> throwError $ InferenceError e (show a))

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

addVariableEnv :: MonadState InfEnv m => String -> TypeBox -> m ()
addVariableEnv s t = modify (addEnv s t)

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

updateEnvM :: (MonadError GalcError m, MonadState InfEnv m)
          => [Constraint] -> InfEnv -> m ()
updateEnvM constr =
  put . fmap ( \(Hide t) -> maybe (Hide t) id (typeRewrite constr t) )

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

getUnifications :: [InfEnv] -> [Constraint]
getUnifications = aux . concatMap toList
  where
    aux :: [(String,TypeBox)] -> [Constraint]
    aux [] = []
    aux ((n, Hide t):xs) =
      (map (\(_, Hide t') -> t :=: t') . filter ((==) n . fst) $ xs) ++ aux xs

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

getFreshT :: MonadFresh [String] String m => m (Type Var)
getFreshT = getFreshLift (TVar . ('t':))

-------------------------------------------------------------------------------
infer' :: (
           MonadFresh [String] String m,
           MonadError GalcError m,
           MonadState InfEnv m
           )
       => S -> m RType
-------------------------------------------------------------------------------
infer' (RefS _ _) = throwError $ ImpossibleError
-------------------------------------------------------------------------------
infer' (RefExtS _ d) = return d
-------------------------------------------------------------------------------
infer' (BotS _) = do
  t1 <- getFreshT
  t2 <- getFreshT
  return $ Exists (Rel t1 t2) BOT
-------------------------------------------------------------------------------
infer' (TopS _) = do
  t1 <- getFreshT
  t2 <- getFreshT
  return $ Exists (Rel t1 t2) TOP
-------------------------------------------------------------------------------
infer' a@(NegS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify [tr :=: Rel t1 t2]
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r' <- rCast constr (Rel t1'' t2'') r
  updateEnvM constr envR
  return $ Exists (Rel t1'' t2'') (NEG r')
-------------------------------------------------------------------------------
infer' a@(MeetS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT; t1' <- getFreshT; t2' <- getFreshT
  constr <- unify $
    [tr1 :=: Rel t1 t2, tr2 :=: Rel t1' t2', t1 :=: t1', t2 :=: t2'] ++ unif
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r1' <- rCast constr (Rel t1'' t2'') r1
  r2' <- rCast constr (Rel t1'' t2'') r2
  updateEnvM constr envR
  return $ Exists (Rel t1'' t2'') (MEET r1' r2')
-------------------------------------------------------------------------------
infer' a@(JoinS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT; t1' <- getFreshT; t2' <- getFreshT
  constr <- unify $
    [tr1 :=: Rel t1 t2, tr2 :=: Rel t1' t2', t1 :=: t1', t2 :=: t2'] ++ unif
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r1' <- rCast constr (Rel t1'' t2'') r1
  r2' <- rCast constr (Rel t1'' t2'') r2
  updateEnvM constr envR
  return $ Exists (Rel t1'' t2'') (JOIN r1' r2')
-------------------------------------------------------------------------------
infer' (IdS _) = do
  t <- getFreshT
  return $ Exists (Rel t t) ID
-------------------------------------------------------------------------------
infer' a@(ConvS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify [tr :=: Rel t1 t2]
  Hide t1' <- typeRewriteE constr t1
  Hide t2' <- typeRewriteE constr t2
  r' <- rCast constr (Rel t1' t2') r
  updateEnvM constr envR
  return $ Exists (Rel t2' t1') (CONV r')
-------------------------------------------------------------------------------
infer' a@(CompS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT; t2' <- getFreshT; t3 <- getFreshT
  constr <-  unify $
    [tr1 :=: Rel t3 t2, tr2 :=: Rel t2' t1, t2 :=: t2'] ++ unif
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  Hide t3'' <- typeRewriteE constr t3
  r1' <- rCast constr (Rel t3'' t2'') r1
  r2' <- rCast constr (Rel t2'' t1'') r2
  updateEnvM constr envR
  return $ Exists (Rel t3'' t1'') (COMP t2'' r1' r2')
-------------------------------------------------------------------------------
infer' a@(SplitS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t1' <- getFreshT
  constr <- unify $
    [tr1 :=: Rel t2 t1, tr2 :=: Rel t3 t1', t1 :=: t1'] ++ unif
  Hide t1''  <- typeRewriteE constr t1
  Hide t2''  <- typeRewriteE constr t2
  Hide t3''  <- typeRewriteE constr t3
  r1' <- rCast constr (Rel t2'' t1'') r1
  r2' <- rCast constr (Rel t3'' t1'') r2
  updateEnvM constr envR
  return $ Exists (Rel (Prod t2'' t3'') t1'') (SPLIT r1' r2')
-------------------------------------------------------------------------------
infer' a@(OrdS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t <- getFreshT
  constr <- unify [tr :=: Ord t]
  Hide t'' <- typeRewriteE constr t
  r' <- rCast constr (Ord t'') r
  updateEnvM constr envR
  return $ Exists (Rel t'' t'') (ORD r')
-------------------------------------------------------------------------------
infer' a@(FunS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify [tr :=: Fun t2 t1]
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r' <- rCast constr (Fun t2'' t1'') r
  updateEnvM constr envR
  return $ Exists (Rel t2'' t1'') (FUN r')
-------------------------------------------------------------------------------
infer' a@(LeftsecS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT
  constr <- unify $ [tr1 :=: Fun t1 (Prod t2 t3), t2 :=: tr2] ++ unif
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  Hide t3'' <- typeRewriteE constr t3
  r2' <- rCast constr t2'' r2
  r1' <- rCast constr (Fun t1'' (Prod t2'' t3'')) r1
  updateEnvM constr envR
  return $ Exists (Fun t1'' t3'') (LEFTSEC t2'' r1' r2')
-------------------------------------------------------------------------------
infer' a@(RightsecS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT
  constr <- unify $ [tr1 :=: Fun t1 (Prod t2 t3), t3 :=: tr2] ++ unif
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  Hide t3'' <- typeRewriteE constr t3
  r2' <- rCast constr t3'' r2
  r1' <- rCast constr (Fun t1'' (Prod t2'' t3'')) r1
  updateEnvM constr envR
  return $ Exists (Fun t1'' t2'') (RIGHTSEC t3'' r1' r2')
-------------------------------------------------------------------------------
infer' a@(ApplyS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify $ [tr1 :=: Fun t1 t2, t2 :=: tr2] ++ unif
  Hide t2'' <- typeRewriteE constr t2
  Hide t1'' <- typeRewriteE constr t1
  r1' <- rCast constr (Fun t1'' t2'') r1
  r2' <- rCast constr t2'' r2
  updateEnvM constr envR
  return $ Exists t1'' (APPLY t2'' r1' r2')
-------------------------------------------------------------------------------
infer' (DefS _ n (Hide t)) = return $ Exists t (DEF n t)
-------------------------------------------------------------------------------
infer' (VarS _ n) = do
  t <- getFreshT
  addVariableEnv n (Hide t)
  return $ Exists t (Var n)
-------------------------------------------------------------------------------
infer' a@(ProdS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t4 <- getFreshT
  constr <- unify $ [tr1 :=: Rel t3 t1, tr2 :=: Rel t4 t2] ++ unif
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  Hide t3'' <- typeRewriteE constr t3
  Hide t4'' <- typeRewriteE constr t4
  r1' <- rCast constr (Rel t3'' t1'') r1
  r2' <- rCast constr (Rel t4'' t2'') r2
  updateEnvM constr envR
  return $ Exists (Rel (Prod t3'' t4'') (Prod t1'' t2'')) (PROD r1' r2')
-------------------------------------------------------------------------------
infer' a@(EitherS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t4 <- getFreshT
  constr <- unify $ [tr1 :=: Rel t3 t1, tr2 :=: Rel t4 t2] ++ unif
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  Hide t3'' <- typeRewriteE constr t3
  Hide t4'' <- typeRewriteE constr t4
  r1' <- rCast constr (Rel t3'' t1'') r1
  r2' <- rCast constr (Rel t4'' t2'') r2
  updateEnvM constr envR
  return $ Exists (Rel (Either t3'' t4'') (Either t1'' t2'')) (EITHER r1' r2')
-------------------------------------------------------------------------------
infer' a@(MaybeS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify [tr :=: Rel t2 t1]
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r1' <- rCast constr (Rel t2'' t1'') r
  updateEnvM constr envR
  return $ Exists (Rel (Maybe t2'') (Maybe t1'')) (MAYBE r1')
-------------------------------------------------------------------------------
infer' a@(ListS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify [tr :=: Rel t2 t1]
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r1' <- rCast constr (Rel t2'' t1'') r
  updateEnvM constr envR
  return $ Exists (Rel (List t2'') (List t1'')) (LIST r1')
-------------------------------------------------------------------------------
infer' a@(SetS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify [tr :=: Rel t2 t1]
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r1' <- rCast constr (Rel t2'' t1'') r
  updateEnvM constr envR
  return $ Exists (Rel (Set t2'') (Set t1'')) (SET r1')
-------------------------------------------------------------------------------
infer' a@(MapS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT
  constr <- unify [tr :=: Rel t2 t1]
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r1' <- rCast constr (Rel t2'' t1'') r
  updateEnvM constr envR
  return $ Exists (Rel (Map t3 t2'') (Map t3 t1'')) (MAP r1')
-------------------------------------------------------------------------------
infer' a@(ReynoldsS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t4 <- getFreshT
  constr <- unify $ [tr1 :=: Rel t2 t1, tr2 :=: Rel t4 t3] ++ unif
  Hide t1' <- typeRewriteE constr t1
  Hide t2' <- typeRewriteE constr t2
  Hide t3' <- typeRewriteE constr t3
  Hide t4' <- typeRewriteE constr t4
  r1' <- rCast constr (Rel t2' t1') r1
  r2' <- rCast constr (Rel t4' t3') r2
  updateEnvM constr envR
  return $ Exists (Rel (Fun t2' t4') (Fun t1' t3')) (REYNOLDS r1' r2')
-------------------------------------------------------------------------------
infer' (FIdS _) = do
  t <- getFreshT
  return $ Exists (Fun t t) FId
-------------------------------------------------------------------------------
infer' a@(FCompS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t2' <- getFreshT
  constr <- unify $
    [tr1 :=: Fun t1 t2, tr2 :=: Fun t2' t3, t2 :=: t2'] ++ unif
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  Hide t3'' <- typeRewriteE constr t3
  r1' <- rCast constr (Fun t1'' t2'') r1
  r2' <- rCast constr (Fun t2'' t3'') r2
  updateEnvM constr envR
  return $ Exists (Fun t1'' t3'') (FComp t2'' r1' r2')
-------------------------------------------------------------------------------
infer' (OIdS _) = do
  t <- getFreshT
  return $ Exists (Ord t) OId
-------------------------------------------------------------------------------
infer' a@(OCompS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t <- getFreshT; t' <- getFreshT
  constr <- unify $ [tr1 :=: Ord t, tr2 :=: Ord t', t :=: t'] ++ unif
  Hide t'' <- typeRewriteE constr t
  r1' <- rCast constr (Ord t'') r1
  r2' <- rCast constr (Ord t'') r2
  updateEnvM constr envR
  return $ Exists (Ord t'') (OComp r1' r2')
-------------------------------------------------------------------------------
infer' a@(OConvS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t <- getFreshT
  constr <- unify [tr :=: Ord t]
  Hide t'' <- typeRewriteE constr t
  r' <- rCast constr (Ord t'') r
  updateEnvM constr envR
  return $ Exists (Ord t'') (OConv r')
-------------------------------------------------------------------------------
infer' a@(OProdS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t <- getFreshT
  constr <- unify [tr :=: Ord t]
  Hide t'' <- typeRewriteE constr t
  r' <- rCast constr (Ord t'') r
  updateEnvM constr envR
  return $ Exists (Ord (Prod t'' t'')) (OProd r')
-------------------------------------------------------------------------------
infer' a@(OJoinS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t <- getFreshT
  constr <- unify [tr :=: Ord t]
  Hide t'' <- typeRewriteE constr t
  r' <- rCast constr (Ord t'') r
  updateEnvM constr envR
  return $ Exists (Fun t'' (Prod t'' t'')) (OJoin r')
-------------------------------------------------------------------------------
infer' a@(OMeetS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t <- getFreshT
  constr <- unify [tr :=: Ord t]
  Hide t'' <- typeRewriteE constr t
  r' <- rCast constr (Ord t'') r
  updateEnvM constr envR
  return $ Exists (Fun t'' (Prod t'' t'')) (OMeet r')
-------------------------------------------------------------------------------
infer' a@(OMaxS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t <- getFreshT
  constr <- unify [tr :=: Ord t]
  Hide t'' <- typeRewriteE constr t
  r' <- rCast constr (Ord t'') r
  updateEnvM constr envR
  return $ Exists t'' (OMax r')
-------------------------------------------------------------------------------
infer' a@(OMinS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t <- getFreshT
  constr <- unify [tr :=: Ord t]
  Hide t'' <- typeRewriteE constr t
  r' <- rCast constr (Ord t'') r
  updateEnvM constr envR
  return $ Exists t'' (OMin r')
-------------------------------------------------------------------------------
infer' a@(GDefS _ n f1a f2a o1a o2a) = catchInfer a $ do
  (Exists tf1 f1, envF1) <- inferUni f1a
  (Exists tf2 f2, envF2) <- inferUni f2a
  (Exists to1 o1, envO1) <- inferUni o1a
  (Exists to2 o2, envO2) <- inferUni o2a
  t1   <- getFreshT; t2   <- getFreshT
  t1'  <- getFreshT; t2'  <- getFreshT
  t1'' <- getFreshT; t2'' <- getFreshT
  let envR = envF1 `Map.union` envF2 `Map.union` envO1 `Map.union` envO2
      unif = getUnifications [envF1,envF2,envO1,envO2]
  constr <- unify $
    [tf1 :=: Fun t1 t2, tf2 :=: Fun t2' t1', to1 :=: Ord t1'', to2 :=: Ord t2'',
     t1 :=: t1', t1' :=: t1'', t2 :=: t2', t2' :=: t2''] ++ unif
  Hide t1''' <- typeRewriteE constr t1
  Hide t2''' <- typeRewriteE constr t2
  f1' <- rCast constr (Fun t1''' t2''') f1
  f2' <- rCast constr (Fun t2''' t1''') f2
  o1' <- rCast constr (Ord t1''') o1
  o2' <- rCast constr (Ord t2''') o2
  updateEnvM constr envR
  return $ Exists (GC t1''' t2''') (GDef n f1' f2' o1' o2')
-------------------------------------------------------------------------------
infer' (GIdS _) = do
  t <- getFreshT
  return $ Exists (GC t t) GId
-------------------------------------------------------------------------------
infer' a@(GCompS _ r1a r2a) = catchInfer a $ do
  (Exists tr1 r1, Exists tr2 r2, unif, envR) <- inferBin r1a r2a
  t1 <- getFreshT; t2 <- getFreshT; t3 <- getFreshT; t2' <- getFreshT
  constr <- unify $
    [tr1 :=: GC t1 t2, tr2 :=: GC t2' t3, t2 :=: t2'] ++ unif
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  Hide t3'' <- typeRewriteE constr t3
  r1' <- rCast constr (GC t1'' t2'') r1
  r2' <- rCast constr (GC t2'' t3'') r2
  updateEnvM constr envR
  return $ Exists (GC t1'' t3'') (GComp t2'' r1' r2')
-------------------------------------------------------------------------------
infer' a@(GConvS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify [tr :=: GC t1 t2]
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r' <- rCast constr (GC t1'' t2'') r
  updateEnvM constr envR
  return $ Exists (GC t2'' t1'') (GConv r')
-------------------------------------------------------------------------------
infer' a@(GLAdjS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify [tr :=: GC t1 t2]
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r' <- rCast constr (GC t1'' t2'') r
  updateEnvM constr envR
  return $ Exists (Fun t1'' t2'') (GLAdj r')
-------------------------------------------------------------------------------
infer' a@(GUAdjS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify [tr :=: GC t1 t2]
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r' <- rCast constr (GC t1'' t2'') r
  updateEnvM constr envR
  return $ Exists (Fun t2'' t1'') (GUAdj r')
-------------------------------------------------------------------------------
infer' a@(GLOrdS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify [tr :=: GC t1 t2]
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r' <- rCast constr (GC t1'' t2'') r
  updateEnvM constr envR
  return $ Exists (Ord t1'') (GLOrd t2'' r')
-------------------------------------------------------------------------------
infer' a@(GUOrdS _ ra) = catchInfer a $ do
  (Exists tr r, envR) <- inferUni ra
  t1 <- getFreshT; t2 <- getFreshT
  constr <- unify [tr :=: GC t1 t2]
  Hide t1'' <- typeRewriteE constr t1
  Hide t2'' <- typeRewriteE constr t2
  r' <- rCast constr (GC t1'' t2'') r
  updateEnvM constr envR
  return $ Exists (Ord t2'') (GUOrd t1'' r')
-------------------------------------------------------------------------------

inferUni :: (MonadError GalcError m,
             MonadState InfEnv m,
             MonadFresh [String] String m)
         => S -> m (RType, InfEnv)
inferUni r = do
  x <- infer' r
  envR <- get
  put emptyEnv
  return (x, envR)

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

inferBin :: (MonadError GalcError m,
             MonadState InfEnv m,
             MonadFresh [String] String m)
         => S -> S -> m (RType, RType, [Constraint], InfEnv)
inferBin r1 r2 = do
  (x, envR1) <- inferUni r1
  (y, envR2) <- inferUni r2
  let envR = envR1 `Map.union` envR2
      unif = getUnifications [envR1,envR2]
  return (x,y,unif,envR)

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

 

Theme by Vikram Singh | Powered by WebSVN v2.3.3