@@ -14,6 +14,7 @@ import Agda.Compiler.Backend hiding ( topLevelModuleName )
1414import Agda.Compiler.Common ( topLevelModuleName )
1515
1616import Agda.Syntax.Common
17+ import Agda.Syntax.Internal
1718import Agda.Syntax.Position
1819import qualified Agda.Syntax.Concrete as C
1920import Agda.Syntax.Scope.Base ( inverseScopeLookupName )
@@ -65,7 +66,9 @@ isSpecialName f rules = let pretty = prettyShow f in case lookupRules pretty rul
6566 where
6667 noImport x = Just (hsName x, Nothing )
6768 withImport mod x =
68- let imp = Import (hsModuleName mod ) Unqualified Nothing (hsName x)
69+ let imp = Import (hsModuleName mod ) Unqualified Nothing (hsName x) (Hs. NoNamespace () )
70+ -- ^ TODO: add an option to specify this in the config file (whether it is a type or not)
71+ -- as far as I know, there are no type operators in Prelude, but maybe a self-defined one could cause trouble
6972 in Just (hsName x, Just imp)
7073
7174 lookupRules :: String -> Rewrites -> Maybe (Hs. Name () , Maybe Import )
@@ -104,8 +107,13 @@ compileQName f
104107 || prettyShow mod0 `elem` primMonadModules
105108 qual <- if | skipModule -> return Unqualified
106109 | otherwise -> getQualifier (fromMaybe f parent) mod
107- let (mod', mimp) = mkImport mod qual par hf
108- qf = qualify mod' hf qual
110+ -- we only calculate this when dealing with type operators; usually that's where 'type' prefixes are needed in imports
111+ namespace <- (case hf of
112+ Hs. Symbol _ _ -> getNamespace f
113+ Hs. Ident _ _ -> return (Hs. NoNamespace () ))
114+ let
115+ (mod', mimp) = mkImport mod qual par hf namespace
116+ qf = qualify mod' hf qual
109117
110118 -- add (possibly qualified) import
111119 whenJust (mimpBuiltin <|> mimp) tellImport
@@ -147,15 +155,32 @@ compileQName f
147155 primModules = [" Agda.Builtin" , " Haskell.Prim" , " Haskell.Prelude" ]
148156 primMonadModules = [" Haskell.Prim.Monad.Dont" , " Haskell.Prim.Monad.Do" ]
149157
150- mkImport mod qual par hf
158+ -- Determine whether it is a type operator or an "ordinary" operator.
159+ -- _getSort is not for that; e. g. a data has the same sort as its constructor.
160+ getNamespace :: QName -> C (Hs. Namespace () )
161+ getNamespace qName = do
162+ definition <- getConstInfo qName
163+ case isSort $ unEl $ getResultType $ defType definition of
164+ Just _ -> (reportSDoc " agda2hs.name" 25 $ text $ (prettyShow $ nameCanonical $ qnameName f)
165+ ++ " is a type operator; will add \" type\" prefix before it" ) >>
166+ return (Hs. TypeNamespace () )
167+ _ -> return (Hs. NoNamespace () )
168+
169+ -- Gets the type of the result of the function (the type after the last "->").
170+ getResultType :: Type -> Type
171+ getResultType typ = case (unEl typ) of
172+ (Pi _ absType) -> getResultType $ unAbs absType
173+ _ -> typ
174+
175+ mkImport mod qual par hf maybeIsType
151176 -- make sure the Prelude is properly qualified
152177 | any (`isPrefixOf` pp mod ) primModules
153178 = if isQualified qual then
154179 let mod' = hsModuleName " Prelude"
155- in (mod', Just (Import mod' qual Nothing hf))
180+ in (mod', Just (Import mod' qual Nothing hf maybeIsType ))
156181 else (mod , Nothing )
157182 | otherwise
158- = (mod , Just (Import mod qual par hf))
183+ = (mod , Just (Import mod qual par hf maybeIsType ))
159184
160185hsTopLevelModuleName :: TopLevelModuleName -> Hs. ModuleName ()
161186hsTopLevelModuleName = hsModuleName . intercalate " ." . map unpack
0 commit comments