@@ -667,7 +667,8 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
667 -- Now build the RHS, using the type of the LHS as the goal.
667 -- Now build the RHS, using the type of the LHS as the goal.
668 i <- getIState -- new implicits from where block
668 i <- getIState -- new implicits from where block
669 logElab 5 (showTmImpls (expandParams decorate newargs defs (defs \\ decls) rhs_in))
669 logElab 5 (showTmImpls (expandParams decorate newargs defs (defs \\ decls) rhs_in))
670+ let rhs = rhs_trans info $
670− let rhs = addImplBoundInf i (map fst newargs_all) (defs \\ decls)
671+ addImplBoundInf i (map fst newargs_all) (defs \\ decls)
671 (expandParams decorate newargs defs (defs \\ decls) rhs_in)
672 (expandParams decorate newargs defs (defs \\ decls) rhs_in)
672 logElab 2 $ "RHS: " ++ show (map fst newargs_all) ++ " " ++ showTmImpls rhs
673 logElab 2 $ "RHS: " ++ show (map fst newargs_all) ++ " " ++ showTmImpls rhs
673 ctxt <- getContext -- new context with where block added
674 ctxt <- getContext -- new context with where block added
@@ -861,7 +862,7 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
861 (clhs, clhsty) <- recheckC fc id [] lhs_tm
862 (clhs, clhsty) <- recheckC fc id [] lhs_tm
862 logElab 5 ("Checked " ++ show clhs)
863 logElab 5 ("Checked " ++ show clhs)
863 let bargs = getPBtys (explicitNames (normalise ctxt [] lhs_tm))
864 let bargs = getPBtys (explicitNames (normalise ctxt [] lhs_tm))
864− let wval = addImplBound i (map fst bargs) wval_in
865+ let wval = rhs_trans info $ addImplBound i (map fst bargs) wval_in
865 logElab 5 ("Checking " ++ showTmImpls wval)
866 logElab 5 ("Checking " ++ showTmImpls wval)
866 -- Elaborate wval in this context
867 -- Elaborate wval in this context
867 ((wval', defer, is, ctxt', newDecls, highlights, newGName), _) <-
868 ((wval', defer, is, ctxt', newDecls, highlights, newGName), _) <-
@@ -959,7 +960,10 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
959 logElab 3 ("with block " ++ show wb)
960 logElab 3 ("with block " ++ show wb)
960 -- propagate totality assertion to the new definitions
961 -- propagate totality assertion to the new definitions
961 when (AssertTotal `elem` opts) $ setFlags wname [AssertTotal]
962 when (AssertTotal `elem` opts) $ setFlags wname [AssertTotal]
964+ let rhstrans' = updateWithTerm i mpn wname lhs (map fst bargs_pre) (map fst (bargs_post))
962− mapM_ (rec_elabDecl info EAll info) wb
966+ mapM_ (rec_elabDecl info EAll (info { rhs_trans = rhstrans' })) wb
964 -- rhs becomes: fname' ps_pre wval ps_post Refl
968 -- rhs becomes: fname' ps_pre wval ps_post Refl
965 let rhs = PApp fc (PRef fc [] wname)
969 let rhs = PApp fc (PRef fc [] wname)
@@ -1001,9 +1005,8 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
1001 getImps _ = []
1005 getImps _ = []
1003 mkAuxC pn wname lhs ns ns' (PClauses fc o n cs)
1007 mkAuxC pn wname lhs ns ns' (PClauses fc o n cs)
1004− | True = do cs' <- mapM (mkAux pn wname lhs ns ns') cs
1008+ = do cs' <- mapM (mkAux pn wname lhs ns ns') cs
1005 return $ PClauses fc o wname cs'
1009 return $ PClauses fc o wname cs'
1006− | otherwise = ifail $ show fc ++ "with clause uses wrong function name " ++ show n
1007 mkAuxC pn wname lhs ns ns' d = return $ d
1010 mkAuxC pn wname lhs ns ns' d = return $ d
1009 mkAux pn wname toplhs ns ns' (PClause fc n tm_in (w:ws) rhs wheres)
1012 mkAux pn wname toplhs ns ns' (PClause fc n tm_in (w:ws) rhs wheres)
@@ -1034,6 +1037,8 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
1034 addArg (PApp fc f args) w = PApp fc f (args ++ [pexp w])
1037 addArg (PApp fc f args) w = PApp fc f (args ++ [pexp w])
1035 addArg (PRef fc hls f) w = PApp fc (PRef fc hls f) [pexp w]
1038 addArg (PRef fc hls f) w = PApp fc (PRef fc hls f) [pexp w]
1040+ -- ns, arguments which don't depend on the with argument
1041+ -- ns', arguments which do
1037 updateLHS n pn wname mvars ns_in ns_in' (PApp fc (PRef fc' hls' n') args) w
1042 updateLHS n pn wname mvars ns_in ns_in' (PApp fc (PRef fc' hls' n') args) w
1038 = let ns = map (keepMvar (map fst mvars) fc') ns_in
1043 = let ns = map (keepMvar (map fst mvars) fc') ns_in
1039 ns' = map (keepMvar (map fst mvars) fc') ns_in' in
1044 ns' = map (keepMvar (map fst mvars) fc') ns_in' in
@@ -1046,9 +1051,56 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
1046 updateLHS n pn wname mvars ns_in ns_in' tm w
1051 updateLHS n pn wname mvars ns_in ns_in' tm w
1047 = updateLHS n pn wname mvars ns_in ns_in' (PApp fc tm []) w
1052 = updateLHS n pn wname mvars ns_in ns_in' (PApp fc tm []) w
1054+ -- Only keep a var as a pattern variable in the with block if it's
1055+ -- matched in the top level pattern
1049 keepMvar mvs fc v | v `elem` mvs = PRef fc [] v
1056 keepMvar mvs fc v | v `elem` mvs = PRef fc [] v
1050 | otherwise = Placeholder
1057 | otherwise = Placeholder
1059+ updateWithTerm :: IState -> Maybe Name -> Name -> PTerm -> [Name] -> [Name] -> PTerm -> PTerm
1060+ updateWithTerm ist pn wname toplhs ns_in ns_in' tm
1061+ = mapPT updateApp tm
1063+ arity (PApp _ _ as) = length as
1066+ lhs_arity = arity toplhs
1068+ updateApp wtm@(PWithApp fcw tm warg) =
1069+ case matchClause ist toplhs tm of
1070+ Left _ -> PElabError (Msg (show fc ++ ":with application does not match top level"))
1072+ let ns = map (keepMvar (map fst mvars) fcw) ns_in
1073+ ns' = map (keepMvar (map fst mvars) fcw) ns_in'
1074+ wty = lookupTyExact wname (tt_ctxt ist)
1075+ res = substMatches mvars $
1076+ PApp fcw (PRef fcw [] wname)
1077+ (map pexp ns ++ pexp warg : (map pexp ns') ++
1080+ Just pnm -> [pexp (PRef fc [] pnm)]) in
1082+ Nothing -> res -- can't happen!
1083+ Just ty -> addResolves ty res
1086+ addResolves ty (PApp fc f args) = PApp fc f (addResolvesArgs fc ty args)
1087+ addResolves ty tm = tm
1089+ -- if an argument's type is a type class, and is otherwise to
1090+ -- be inferred, then resolve it with instance search
1091+ -- This is something of a hack, because matching on the top level
1092+ -- application won't find this information for us
1093+ addResolvesArgs :: FC -> Term -> [PArg] -> [PArg]
1094+ addResolvesArgs fc (Bind n (Pi _ ty _) sc) (a : args)
1095+ | (P _ cn _, _) <- unApply ty,
1096+ getTm a == Placeholder
1097+ = case lookupCtxtExact cn (idris_classes ist) of
1098+ Just _ -> a { getTm = PResolveTC fc } : addResolvesArgs fc sc args
1099+ Nothing -> a : addResolvesArgs fc sc args
1100+ addResolvesArgs fc (Bind n (Pi _ ty _) sc) (a : args)
1101+ = a : addResolvesArgs fc sc args
1102+ addResolvesArgs fc _ args = args
1052 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1104 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
1053 fullApp x = x
1105 fullApp x = x
@@ -1059,3 +1111,19 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
1059 split deps [] pre = (reverse pre, [])
1111 split deps [] pre = (reverse pre, [])
1061 abstract wn wv wty (n, argty) = (n, substTerm wv (P Bound wn wty) argty)
1113 abstract wn wv wty (n, argty) = (n, substTerm wv (P Bound wn wty) argty)
1115+-- Apply a transformation to all RHSes and nested RHSs
1116+mapRHS :: (PTerm -> PTerm) -> PClause -> PClause
1117+mapRHS f (PClause fc n lhs args rhs ws)
1118+ = PClause fc n lhs args (f rhs) (map (mapRHSdecl f) ws)
1119+mapRHS f (PWith fc n lhs args warg prf ws)
1120+ = PWith fc n lhs args (f warg) prf (map (mapRHSdecl f) ws)
1121+mapRHS f (PClauseR fc args rhs ws)
1122+ = PClauseR fc args (f rhs) (map (mapRHSdecl f) ws)
1123+mapRHS f (PWithR fc args warg prf ws)
1124+ = PWithR fc args (f warg) prf (map (mapRHSdecl f) ws)
1126+mapRHSdecl :: (PTerm -> PTerm) -> PDecl -> PDecl
1127+mapRHSdecl f (PClauses fc opt n cs)
1128+ = PClauses fc opt n (map (mapRHS f) cs)