@@ -624,12 +624,27 @@ elabClause info tcgen (_, PWith fc fname lhs_in withs wval_in withblock)
624 addDeferred def'
624 addDeferred def'
625 mapM_ (elabCaseBlock info) is
625 mapM_ (elabCaseBlock info) is
626 (cwval, cwvalty) <- recheckC fc [] (getInferTerm wval')
626 (cwval, cwvalty) <- recheckC fc [] (getInferTerm wval')
627+ let cwvaltyN = explicitNames cwvalty
628+ let cwvalN = explicitNames cwval
627− logLvl 3 ("With type " ++ show cwvalty ++ "\nRet type " ++ show ret_ty)
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)
628 windex <- getName
638 windex <- getName
629 -- build a type declaration for the new function:
639 -- build a type declaration for the new function:
630− -- (ps : Xs) -> (withval : cwvalty) -> ret_ty
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)
631− let wtype = bindTyArgs Pi (bargs ++ [(MN 0 "warg", getRetTy cwvalty)]) ret_ty
644+ let wtype = bindTyArgs Pi (bargs_pre ++
645+ (MN 0 "warg", wargtype) :
646+ map (abstract (MN 0 "warg") wargval) bargs_post) ret_ty
632− logLvl 3 ("New function type " ++ show wtype)
647+ logLvl 1 ("New function type " ++ show wtype)
633 let wname = MN windex (show fname)
648 let wname = MN windex (show fname)
634 let imps = getImps wtype -- add to implicits context
649 let imps = getImps wtype -- add to implicits context
635 put (i { idris_implicits = addDef wname imps (idris_implicits i) })
650 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)
640 -- in the subdecls, lhs becomes:
655 -- in the subdecls, lhs becomes:
641 -- fname pats | wpat [rest]
656 -- fname pats | wpat [rest]
642 -- ==> fname' ps wpat [rest], match pats against toplevel for ps
657 -- ==> fname' ps wpat [rest], match pats against toplevel for ps
643− wb <- mapM (mkAuxC wname lhs (map fst bargs)) withblock
658+ wb <- mapM (mkAuxC wname lhs (map fst bargs_pre) (map fst bargs_post))
644− logLvl 5 ("with block " ++ show wb)
660+ logLvl 1 ("with block " ++ show wb)
645 mapM_ (elabDecl EAll info) wb
661 mapM_ (elabDecl EAll info) wb
647 -- rhs becomes: fname' ps wval
663 -- rhs becomes: fname' ps wval
648− let rhs = PApp fc (PRef fc wname) (map (pexp . (PRef fc) . fst) bargs ++
664+ let rhs = PApp fc (PRef fc wname)
665+ (map (pexp . (PRef fc) . fst) bargs_pre ++
649− [pexp wval])
666+ pexp wval :
667+ (map (pexp . (PRef fc) . fst) bargs_post))
650− logLvl 3 ("New RHS " ++ show rhs)
668+ logLvl 1 ("New RHS " ++ show rhs)
651 ctxt <- getContext -- New context with block added
669 ctxt <- getContext -- New context with block added
653 ((rhs', defer, is), _) <-
671 ((rhs', defer, is), _) <-
@@ -666,41 +684,45 @@ elabClause info tcgen (_, PWith fc fname lhs_in withs wval_in withblock)
666 getImps (Bind n (Pi _) t) = pexp Placeholder : getImps t
684 getImps (Bind n (Pi _) t) = pexp Placeholder : getImps t
667 getImps _ = []
685 getImps _ = []
669− mkAuxC wname lhs ns (PClauses fc o n cs)
687+ mkAuxC wname lhs ns ns' (PClauses fc o n cs)
670− | True = do cs' <- mapM (mkAux wname lhs ns) cs
688+ | True = do cs' <- mapM (mkAux wname lhs ns ns') cs
671 return $ PClauses fc o wname cs'
689 return $ PClauses fc o wname cs'
672 | otherwise = fail $ show fc ++ "with clause uses wrong function name " ++ show n
690 | 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
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)
676 = do i <- get
694 = do i <- get
677 let tm = addImpl i tm_in
695 let tm = addImpl i tm_in
678 logLvl 2 ("Matching " ++ showImp True tm ++ " against " ++
696 logLvl 2 ("Matching " ++ showImp True tm ++ " against " ++
679 showImp True toplhs)
697 showImp True toplhs)
680 case matchClause i toplhs tm of
698 case matchClause i toplhs tm of
681 Left _ -> fail $ show fc ++ "with clause does not match top level"
699 Left _ -> fail $ show fc ++ "with clause does not match top level"
682− Right mvars -> do logLvl 3 ("Match vars : " ++ show mvars)
701+ do logLvl 3 ("Match vars : " ++ show mvars)
683− lhs <- updateLHS n wname mvars ns (fullApp tm) w
702+ lhs <- updateLHS n wname mvars ns ns' (fullApp tm) w
684− return $ PClause fc wname lhs ws rhs wheres
703+ return $ PClause fc wname lhs ws rhs wheres
685− mkAux wname toplhs ns (PWith fc n tm_in (w:ws) wval withs)
704+ mkAux wname toplhs ns ns' (PWith fc n tm_in (w:ws) wval withs)
686 = do i <- get
705 = do i <- get
687 let tm = addImpl i tm_in
706 let tm = addImpl i tm_in
688 logLvl 2 ("Matching " ++ showImp True tm ++ " against " ++
707 logLvl 2 ("Matching " ++ showImp True tm ++ " against " ++
689 showImp True toplhs)
708 showImp True toplhs)
690− withs' <- mapM (mkAuxC wname toplhs ns) withs
709+ withs' <- mapM (mkAuxC wname toplhs ns ns') withs
691 case matchClause i toplhs tm of
710 case matchClause i toplhs tm of
692 Left _ -> fail $ show fc ++ "with clause does not match top level"
711 Left _ -> fail $ show fc ++ "with clause does not match top level"
693− Right mvars -> do lhs <- updateLHS n wname mvars ns (fullApp tm) w
713+ do lhs <- updateLHS n wname mvars ns ns' (fullApp tm) w
694− return $ PWith fc wname lhs ws wval withs'
714+ return $ PWith fc wname lhs ws wval withs'
695− mkAux wname toplhs ns c
715+ mkAux wname toplhs ns ns' c
696 = fail $ show fc ++ "badly formed with clause"
716 = fail $ show fc ++ "badly formed with clause"
698− updateLHS n wname mvars ns (PApp fc (PRef fc' n') args) w
718+ updateLHS n wname mvars ns_in ns_in' (PApp fc (PRef fc' n') args) w
699− = let ns' = map (keepMvar (map fst mvars) fc') ns in
719+ = let ns = map (keepMvar (map fst mvars) fc') ns_in
720+ ns' = map (keepMvar (map fst mvars) fc') ns_in' in
700 return $ substMatches mvars $
721 return $ substMatches mvars $
701 PApp fc (PRef fc' wname)
722 PApp fc (PRef fc' wname)
702− (map pexp ns' ++ [pexp w])
723+ (map pexp ns ++ pexp w : (map pexp ns'))
724+ updateLHS n wname mvars ns ns' tm w
703− updateLHS n wname mvars ns tm w = fail $ "Not implemented match " ++ show tm
725+ = fail $ "Not implemented match " ++ show tm
705 keepMvar mvs fc v | v `elem` mvs = PRef fc v
727 keepMvar mvs fc v | v `elem` mvs = PRef fc v
706 | otherwise = Placeholder
728 | otherwise = Placeholder
@@ -708,6 +730,14 @@ elabClause info tcgen (_, PWith fc fname lhs_in withs wval_in withblock)
708 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
730 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
709 fullApp x = x
731 fullApp x = x
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, [])
739+ abstract wn wty (n, argty) = (n, substTerm wty (P Bound wn wty) argty)
711data MArgTy = IA | EA | CA deriving Show
741data MArgTy = IA | EA | CA deriving Show
713elabClass :: ElabInfo -> SyntaxInfo -> String ->
743elabClass :: ElabInfo -> SyntaxInfo -> String ->
@@ -1026,6 +1056,7 @@ pbty (Bind n (PVar t) sc) tm = Bind n (PVTy t) (pbty sc tm)
1026pbty _ tm = tm
1056pbty _ tm = tm
1028getPBtys (Bind n (PVar t) sc) = (n, t) : getPBtys sc
1058getPBtys (Bind n (PVar t) sc) = (n, t) : getPBtys sc
1059+getPBtys (Bind n (PVTy t) sc) = (n, t) : getPBtys sc
1029getPBtys _ = []
1060getPBtys _ = []
1031psolve (Bind n (PVar t) sc) = do solve; psolve sc
1062psolve (Bind n (PVar t) sc) = do solve; psolve sc