agda / agda

Agda is a dependently typed programming language / interactive theorem prover.

Home Page:https://wiki.portal.chalmers.se/agda/pmwiki.php

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Preserve let-bindings when pretty-printing

knisht opened this issue · comments

Consider the following snippet.

data U : Set where
  u : U

test : U
test = let X = U
           a : X
           a = u
       in {!helper a!}  -- C-c C-h

Currently, the signature of helper function is helper : U → U, but it would be better to print helper : (let X = U) → X → U

This would require first that we actually preserve let-bindings in the internal syntax, which we currently don't. This has been discussed as a way to increase sharing (see #514 #3094), but it would indeed also be beneficial to pretty-printing.

For the record, there is already a heuristic that restores let-binding during pretty-printing.

{-# SPECIALIZE tryReifyAsLetBinding :: Term -> TCM Expr -> TCM Expr #-}
-- | Check if the term matches an existing let-binding, in that case use the corresponding variable,
-- otherwise reify using the continuation.
tryReifyAsLetBinding :: MonadReify m => Term -> m Expr -> m Expr
tryReifyAsLetBinding v fallback = ifM (asksTC $ not . envFoldLetBindings) fallback $ do
letBindings <- do
binds <- asksTC (Map.toAscList . envLetBindings)
opened <- forM binds $ \ (name, open) -> (,name) <$> getOpen open
return [ (body, name) | (LetBinding UserWritten body _, name) <- opened, not $ isNoName name ] -- Only fold user-written lets
matchingBindings <- filterM (\t -> checkSyntacticEquality v (fst t) (\_ _ -> return True) (\_ _ -> return False)) letBindings
case matchingBindings of
(_, name) : _ -> return $ A.Var name
[] -> fallback