@@ -624,12 +624,27 @@ elabClause info tcgen (_, PWith fc fname lhs_in withs wval_in withblock)
624624 addDeferred def'
625625 mapM_ (elabCaseBlock info) is
626626 (cwval, cwvalty) <- recheckC fc [] (getInferTerm wval')
627− logLvl 3 ("With type " ++ show cwvalty ++ "\nRet type " ++ show ret_ty)
627+ let cwvaltyN = explicitNames cwvalty
628+ let cwvalN = explicitNames cwval
629+ logLvl 1 ("With type " ++ show cwvalty ++ "\nRet type " ++ show ret_ty)
630+ let pvars = map fst (getPBtys cwvalty)
631+ -- we need the unelaborated term to get the names it depends on
632+ -- rather than a de Bruijn index.
633+ let pdeps = usedNamesIn pvars i (delab i cwvalty)
634+ let (bargs_pre, bargs_post) = split pdeps bargs []
635+ logLvl 1 ("With type " ++ show (getRetTy cwvaltyN) ++
636+ " depends on " ++ show pdeps ++ " from " ++ show pvars)
637+ logLvl 1 ("Pre " ++ show bargs_pre ++ "\nPost " ++ show bargs_post)
628638 windex <- getName
629639 -- build a type declaration for the new function:
630− -- (ps : Xs) -> (withval : cwvalty) -> ret_ty
631− let wtype = bindTyArgs Pi (bargs ++ [(MN 0 "warg", getRetTy cwvalty)]) ret_ty
632− logLvl 3 ("New function type " ++ show wtype)
640+ -- (ps : Xs) -> (withval : cwvalty) -> (ps' : Xs') -> ret_ty
641+ let wargval = getRetTy cwvalN
642+ let wargtype = getRetTy cwvaltyN
643+ logLvl 1 ("Abstract over " ++ show wargval)
644+ let wtype = bindTyArgs Pi (bargs_pre ++
645+ (MN 0 "warg", wargtype) :
646+ map (abstract (MN 0 "warg") wargval) bargs_post) ret_ty
647+ logLvl 1 ("New function type " ++ show wtype)
633648 let wname = MN windex (show fname)
634649 let imps = getImps wtype -- add to implicits context
635650 put (i { idris_implicits = addDef wname imps (idris_implicits i) })
@@ -640,14 +655,17 @@ elabClause info tcgen (_, PWith fc fname lhs_in withs wval_in withblock)
640655 -- in the subdecls, lhs becomes:
641656 -- fname pats | wpat [rest]
642657 -- ==> fname' ps wpat [rest], match pats against toplevel for ps
643− wb <- mapM (mkAuxC wname lhs (map fst bargs)) withblock
644− logLvl 5 ("with block " ++ show wb)
658+ wb <- mapM (mkAuxC wname lhs (map fst bargs_pre) (map fst bargs_post))
659+ withblock
660+ logLvl 1 ("with block " ++ show wb)
645661 mapM_ (elabDecl EAll info) wb
646662
647663 -- rhs becomes: fname' ps wval
648− let rhs = PApp fc (PRef fc wname) (map (pexp . (PRef fc) . fst) bargs ++
649− [pexp wval])
650− logLvl 3 ("New RHS " ++ show rhs)
664+ let rhs = PApp fc (PRef fc wname)
665+ (map (pexp . (PRef fc) . fst) bargs_pre ++
666+ pexp wval :
667+ (map (pexp . (PRef fc) . fst) bargs_post))
668+ logLvl 1 ("New RHS " ++ show rhs)
651669 ctxt <- getContext -- New context with block added
652670 i <- get
653671 ((rhs', defer, is), _) <-
@@ -666,41 +684,45 @@ elabClause info tcgen (_, PWith fc fname lhs_in withs wval_in withblock)
666684 getImps (Bind n (Pi _) t) = pexp Placeholder : getImps t
667685 getImps _ = []
668686
669− mkAuxC wname lhs ns (PClauses fc o n cs)
670− | True = do cs' <- mapM (mkAux wname lhs ns) cs
687+ mkAuxC wname lhs ns ns' (PClauses fc o n cs)
688+ | True = do cs' <- mapM (mkAux wname lhs ns ns') cs
671689 return $ PClauses fc o wname cs'
672690 | otherwise = fail $ show fc ++ "with clause uses wrong function name " ++ show n
673− mkAuxC wname lhs ns d = return $ d
691+ mkAuxC wname lhs ns ns' d = return $ d
674692
675− mkAux wname toplhs ns (PClause fc n tm_in (w:ws) rhs wheres)
693+ mkAux wname toplhs ns ns' (PClause fc n tm_in (w:ws) rhs wheres)
676694 = do i <- get
677695 let tm = addImpl i tm_in
678696 logLvl 2 ("Matching " ++ showImp True tm ++ " against " ++
679697 showImp True toplhs)
680698 case matchClause i toplhs tm of
681699 Left _ -> fail $ show fc ++ "with clause does not match top level"
682− Right mvars -> do logLvl 3 ("Match vars : " ++ show mvars)
683− lhs <- updateLHS n wname mvars ns (fullApp tm) w
684− return $ PClause fc wname lhs ws rhs wheres
685− mkAux wname toplhs ns (PWith fc n tm_in (w:ws) wval withs)
700+ Right mvars ->
701+ do logLvl 3 ("Match vars : " ++ show mvars)
702+ lhs <- updateLHS n wname mvars ns ns' (fullApp tm) w
703+ return $ PClause fc wname lhs ws rhs wheres
704+ mkAux wname toplhs ns ns' (PWith fc n tm_in (w:ws) wval withs)
686705 = do i <- get
687706 let tm = addImpl i tm_in
688707 logLvl 2 ("Matching " ++ showImp True tm ++ " against " ++
689708 showImp True toplhs)
690− withs' <- mapM (mkAuxC wname toplhs ns) withs
709+ withs' <- mapM (mkAuxC wname toplhs ns ns') withs
691710 case matchClause i toplhs tm of
692711 Left _ -> fail $ show fc ++ "with clause does not match top level"
693− Right mvars -> do lhs <- updateLHS n wname mvars ns (fullApp tm) w
694− return $ PWith fc wname lhs ws wval withs'
695− mkAux wname toplhs ns c
712+ Right mvars ->
713+ do lhs <- updateLHS n wname mvars ns ns' (fullApp tm) w
714+ return $ PWith fc wname lhs ws wval withs'
715+ mkAux wname toplhs ns ns' c
696716 = fail $ show fc ++ "badly formed with clause"
697717
698− updateLHS n wname mvars ns (PApp fc (PRef fc' n') args) w
699− = let ns' = map (keepMvar (map fst mvars) fc') ns in
718+ updateLHS n wname mvars ns_in ns_in' (PApp fc (PRef fc' n') args) w
719+ = let ns = map (keepMvar (map fst mvars) fc') ns_in
720+ ns' = map (keepMvar (map fst mvars) fc') ns_in' in
700721 return $ substMatches mvars $
701722 PApp fc (PRef fc' wname)
702− (map pexp ns' ++ [pexp w])
703− updateLHS n wname mvars ns tm w = fail $ "Not implemented match " ++ show tm
723+ (map pexp ns ++ pexp w : (map pexp ns'))
724+ updateLHS n wname mvars ns ns' tm w
725+ = fail $ "Not implemented match " ++ show tm
704726
705727 keepMvar mvs fc v | v `elem` mvs = PRef fc v
706728 | otherwise = Placeholder
@@ -708,6 +730,14 @@ elabClause info tcgen (_, PWith fc fname lhs_in withs wval_in withblock)
708730 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
709731 fullApp x = x
710732
733+ split [] rest pre = (reverse pre, rest)
734+ split deps ((n, ty) : rest) pre
735+ | n `elem` deps = split (deps \\ [n]) rest ((n, ty) : pre)
736+ | otherwise = split deps rest ((n, ty) : pre)
737+ split deps [] pre = (reverse pre, [])
738+
739+ abstract wn wty (n, argty) = (n, substTerm wty (P Bound wn wty) argty)
740+
711741data MArgTy = IA | EA | CA deriving Show
712742
713743elabClass :: ElabInfo -> SyntaxInfo -> String ->
@@ -1026,6 +1056,7 @@ pbty (Bind n (PVar t) sc) tm = Bind n (PVTy t) (pbty sc tm)
10261056pbty _ tm = tm
10271057
10281058getPBtys (Bind n (PVar t) sc) = (n, t) : getPBtys sc
1059+getPBtys (Bind n (PVTy t) sc) = (n, t) : getPBtys sc
10291060getPBtys _ = []
10301061
10311062psolve (Bind n (PVar t) sc) = do solve; psolve sc