agda2hs-1.2: src/Agda2Hs/Compile/Data.hs
module Agda2Hs.Compile.Data where
import qualified Language.Haskell.Exts.Syntax as Hs
import Agda.Compiler.Backend
import Agda.Syntax.Common
import Agda.Syntax.Internal
import Agda.Syntax.Common.Pretty ( prettyShow )
import Agda.TypeChecking.Pretty
import Agda.TypeChecking.Reduce
import Agda.TypeChecking.Substitute
import Agda.TypeChecking.Telescope
import Agda.Utils.Impossible ( __IMPOSSIBLE__ )
import Agda2Hs.Compile.Type ( compileDom, compileTeleBinds )
import Agda2Hs.Compile.Types
import Agda2Hs.Compile.Utils
import Agda2Hs.HsUtils
checkNewtype :: Hs.Name () -> [Hs.QualConDecl ()] -> C ()
checkNewtype name cs = do
checkSingleElement name cs "Newtype must have exactly one constructor in definition"
case head cs of
Hs.QualConDecl () _ _ (Hs.ConDecl () cName types)
-> checkSingleElement cName types "Newtype must have exactly one field in constructor"
compileData :: DataTarget -> [Hs.Deriving ()] -> Definition -> C [Hs.Decl ()]
compileData target ds def = do
let d = hsName $ prettyShow $ qnameName $ defName def
checkValidTypeName d
case theDef def of
Datatype{dataPars = n, dataIxs = numIxs, dataCons = cs} -> do
TelV tel t <- telViewUpTo n (defType def)
reportSDoc "agda2hs.data" 10 $ text "Datatype telescope:" <+> prettyTCM tel
allIndicesErased t
let params = teleArgs tel
addContext tel $ do
binds <- compileTeleBinds tel
cs <- mapM (compileConstructor params) cs
let hd = foldl (Hs.DHApp ()) (Hs.DHead () d) binds
case target of
ToData -> return [Hs.DataDecl () (Hs.DataType ()) Nothing hd cs ds]
ToDataNewType -> do
checkNewtype d cs
return [Hs.DataDecl () (Hs.NewType ()) Nothing hd cs ds]
_ -> __IMPOSSIBLE__
where
allIndicesErased :: Type -> C ()
allIndicesErased t = reduce (unEl t) >>= \case
Pi dom t -> compileDom (absName t) dom >>= \case
DomDropped -> allIndicesErased (unAbs t)
DomType{} -> genericDocError =<< text "Not supported: indexed datatypes"
DomConstraint{} -> genericDocError =<< text "Not supported: constraints in types"
_ -> return ()
compileConstructor :: [Arg Term] -> QName -> C (Hs.QualConDecl ())
compileConstructor params c = checkingVars $ do
reportSDoc "agda2hs.data.con" 15 $ text "compileConstructor" <+> prettyTCM c
reportSDoc "agda2hs.data.con" 20 $ text " params = " <+> prettyTCM params
ty <- (`piApplyM` params) . defType =<< getConstInfo c
reportSDoc "agda2hs.data.con" 20 $ text " ty = " <+> prettyTCM ty
TelV tel _ <- telView ty
let conName = hsName $ prettyShow $ qnameName c
checkValidConName conName
args <- compileConstructorArgs tel
return $ Hs.QualConDecl () Nothing Nothing $ Hs.ConDecl () conName args
compileConstructorArgs :: Telescope -> C [Hs.Type ()]
compileConstructorArgs EmptyTel = return []
compileConstructorArgs (ExtendTel a tel) = compileDom (absName tel) a >>= \case
DomType s hsA -> do
ty <- addTyBang s hsA
(ty :) <$> underAbstraction a tel compileConstructorArgs
DomConstraint hsA -> genericDocError =<< text "Not supported: constructors with class constraints"
DomDropped -> underAbstraction a tel compileConstructorArgs