{-# LANGUAGE CPP #-} module Agda.TypeChecking.Monad.Open ( makeOpen , makeClosed , getOpen , tryOpen ) where import Control.Applicative import Control.Monad import Control.Monad.Error import Data.List import Agda.Syntax.Common import Agda.TypeChecking.Substitute import Agda.TypeChecking.Monad.Base import {-# SOURCE #-} Agda.TypeChecking.Monad.Context #include "../../undefined.h" import Agda.Utils.Impossible -- | Create an open term in the current context. makeOpen :: MonadTCM tcm => a -> tcm (Open a) makeOpen x = do ctx <- getContextId return $ OpenThing ctx x -- | Create an open term which is closed. makeClosed :: a -> Open a makeClosed = OpenThing [] -- | Extract the value from an open term. Must be done in an extension of the -- context in which the term was created. getOpen :: (MonadTCM tcm, Raise a) => Open a -> tcm a getOpen (OpenThing [] x) = return x getOpen (OpenThing ctx x) = do ctx' <- getContextId unless (ctx `isSuffixOf` ctx') $ fail $ "thing out of context (" ++ show ctx ++ " is not a sub context of " ++ show ctx' ++ ")" return $ raise (genericLength ctx' - genericLength ctx) x tryOpen :: (MonadTCM tcm, Raise a) => Open a -> tcm (Maybe a) tryOpen o = liftTCM $ (Just <$> getOpen o) `catchError` \_ -> return Nothing