@@ -8,7 +8,7 @@ Maintainer : The Idris Community.
88
99{-# LANGUAGE PatternGuards #-}
1010{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
11−module Idris.Core.WHNF(whnf, WEnv) where
11+module Idris.Core.WHNF(whnf, whnfArgs, WEnv) where
1212
1313import Idris.Core.CaseTree
1414import Idris.Core.Evaluate hiding (quote)
@@ -37,7 +37,8 @@ type Stack = [StackEntry]
3737data WHNF = WDCon Int Int Bool Name (Term, WEnv) -- ^ data constructor
3838 | WTCon Int Int Name (Type, WEnv) -- ^ type constructor
3939 | WPRef Name (Term, WEnv) -- ^irreducible global (e.g. a postulate)
40− | WBind Name (Binder Term) (Term, WEnv)
40+ | WV Int
41+ | WBind Name (Binder WHNF) (Term, WEnv)
4142 | WApp WHNF (Term, WEnv)
4243 | WConstant Const
4344 | WProj WHNF Int
@@ -46,7 +47,7 @@ data WHNF = WDCon Int Int Bool Name (Term, WEnv) -- ^ data constructor
4647 | WErased
4748 | WImpossible
4849
49−-- | Reduce a *closed* term to weak head normal form.
50+-- | Reduce a term to weak head normal form.
5051whnf :: Context -> Env -> Term -> Term
5152whnf ctxt env tm =
5253 inlineSmall ctxt env $ -- reduce small things in body. This is primarily
@@ -55,6 +56,14 @@ whnf ctxt env tm =
5556 -- easier to read.
5657 quote (do_whnf ctxt (map finalEntry env) tm)
5758
59+-- | Reduce a type so that all arguments are expanded, and all argument types
60+-- are in weak head normal form
61+whnfArgs :: Context -> Env -> Term -> Term
62+whnfArgs ctxt env tm
63+ = case whnf ctxt env tm of
64+ Bind n b@(Pi _ ty _) sc -> Bind n b (whnfArgs ctxt ((n,b):env) sc)
65+ res -> res
66+
5867finalEntry :: (Name, Binder (TT Name)) -> (Name, Binder (TT Name))
5968finalEntry (n, b) = (n, fmap finalise b)
6069
@@ -65,12 +74,13 @@ do_whnf ctxt genv tm = eval (WEnv 0 []) [] tm
6574 eval wenv@(WEnv d env) stk (V i)
6675 | i < length env = let (tm, env') = env !! i in
6776 eval env' stk tm
68− | otherwise = error "Can't happen: WHNF scope error"
77+ | otherwise = WV i
6978 eval wenv@(WEnv d env) stk (Bind n (Let t v) sc)
7079 = eval (WEnv d ((v, wenv) : env)) stk sc
71− eval (WEnv d env) [] (Bind n b sc) = WBind n b (sc, WEnv (d + 1) env)
72− eval (WEnv d env) ((tm, tenv) : stk) (Bind n b sc)
80+ eval (WEnv d env) ((tm, tenv) : stk) (Bind n b@(Lam _) sc)
7381 = eval (WEnv d ((tm, tenv) : env)) stk sc
82+ eval wenv@(WEnv d env) stk (Bind n b sc) -- stk must be empty if well typed
83+ = WBind n (fmap (eval wenv []) b) (sc, WEnv (d + 1) env)
7484
7585 eval env stk (P nt n ty)
7686 | Just (Let t v) <- lookup n genv = eval env stk v
@@ -204,7 +214,8 @@ quote :: WHNF -> Term
204214quote (WDCon t a u n (ty, env)) = P (DCon t a u) n (quoteEnv env ty)
205215quote (WTCon t a n (ty, env)) = P (TCon t a) n (quoteEnv env ty)
206216quote (WPRef n (ty, env)) = P Ref n (quoteEnv env ty)
207−quote (WBind n ty (sc, env)) = Bind n ty (quoteEnv env sc)
217+quote (WV i) = V i
218+quote (WBind n b (sc, env)) = Bind n (fmap quote b) (quoteEnv env sc)
208219quote (WApp f (a, env)) = App Complete (quote f) (quoteEnv env a)
209220quote (WConstant c) = Constant c
210221quote (WProj t i) = Proj (quote t) i