|
| 1 | +-- | Eta-expansion on constructors to fully-apply them, for treeless syntax. |
| 2 | +module Agda.Utils.EtaExpandConstructors (etaExpandConstructors) where |
| 3 | + |
| 4 | +import Data.Bifunctor (second) |
| 5 | + |
| 6 | +import Agda.Syntax.Treeless |
| 7 | +import Agda.TypeChecking.Monad |
| 8 | +import Agda.TypeChecking.Substitute |
| 9 | +import Agda.TypeChecking.Datatypes |
| 10 | +import Agda.Compiler.Treeless.Subst () --instance only |
| 11 | +import Agda.Compiler.Backend |
| 12 | +import Control.Monad.IO.Class (MonadIO(liftIO)) |
| 13 | + |
| 14 | + |
| 15 | +-- | Check whether a treeless term is a constructor applied to (many) terms. |
| 16 | +unSpineCon :: TTerm -> Maybe (QName, [TTerm]) |
| 17 | +unSpineCon (TCon q) = Just (q, []) |
| 18 | +unSpineCon (TApp u v) = second (++ v) <$> unSpineCon u |
| 19 | +unSpineCon _ = Nothing |
| 20 | + |
| 21 | +-- | Return the arity of a constructor |
| 22 | +getConArity :: ConstructorInfo -> Int |
| 23 | +getConArity (DataCon a) = a |
| 24 | +getConArity (RecordCon _ _ a _) = a |
| 25 | + |
| 26 | +-- | Eta-expand treeless constructors. |
| 27 | +etaExpandConstructors :: TTerm -> TCM TTerm |
| 28 | +etaExpandConstructors t | Just (q, args) <- unSpineCon t = do |
| 29 | + arity <- getConArity <$> getConstructorInfo q |
| 30 | + let nargs = length args |
| 31 | + |
| 32 | + if nargs >= arity then -- should really be (==), but just in case |
| 33 | + TApp (TCon q) <$> mapM etaExpandConstructors args |
| 34 | + |
| 35 | + else do |
| 36 | + let nlam = arity - nargs |
| 37 | + exargs <- mapM (etaExpandConstructors . raise nlam) args |
| 38 | + let vars = TVar <$> reverse [0 .. nlam - 1] |
| 39 | + liftIO $ putStrLn $ show vars |
| 40 | + pure $ iterate TLam (TApp (TCon q) $ exargs ++ vars) !! nlam |
| 41 | + |
| 42 | +etaExpandConstructors t = case t of |
| 43 | + TApp u v -> TApp <$> etaExpandConstructors u <*> mapM etaExpandConstructors v |
| 44 | + TLam u -> TLam <$> etaExpandConstructors u |
| 45 | + TLet u v -> TLet <$> etaExpandConstructors u <*> etaExpandConstructors v |
| 46 | + TCase k ci tdef alts -> TCase k ci <$> etaExpandConstructors tdef |
| 47 | + <*> mapM etaExpandAlt alts |
| 48 | + TCoerce u -> TCoerce <$> etaExpandConstructors u |
| 49 | + _ -> pure t |
| 50 | + |
| 51 | +etaExpandAlt :: TAlt -> TCM TAlt |
| 52 | +etaExpandAlt = \case |
| 53 | + TACon q a b -> TACon q a <$> etaExpandConstructors b |
| 54 | + TAGuard a b -> TAGuard a <$> etaExpandConstructors b |
| 55 | + TALit l b -> TALit l <$> etaExpandConstructors b |
0 commit comments