@@ -667,7 +667,8 @@ elabClause info opts (cnum, PClause fc fname lhs_in_as withs rhs_in_as wherebloc
667667 -- Now build the RHS, using the type of the LHS as the goal.
668668 i <- getIState -- new implicits from where block
669669 logElab 5 (showTmImpls (expandParams decorate newargs defs (defs \\ decls) rhs_in))
670− let rhs = addImplBoundInf i (map fst newargs_all) (defs \\ decls)
670+ let rhs = rhs_trans info $
671+ addImplBoundInf i (map fst newargs_all) (defs \\ decls)
671672 (expandParams decorate newargs defs (defs \\ decls) rhs_in)
672673 logElab 2 $ "RHS: " ++ show (map fst newargs_all) ++ " " ++ showTmImpls rhs
673674 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)
861862 (clhs, clhsty) <- recheckC fc id [] lhs_tm
862863 logElab 5 ("Checked " ++ show clhs)
863864 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
865866 logElab 5 ("Checking " ++ showTmImpls wval)
866867 -- Elaborate wval in this context
867868 ((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)
959960 logElab 3 ("with block " ++ show wb)
960961 -- propagate totality assertion to the new definitions
961962 when (AssertTotal `elem` opts) $ setFlags wname [AssertTotal]
962− mapM_ (rec_elabDecl info EAll info) wb
963+ i <- getIState
964+ let rhstrans' = updateWithTerm i mpn wname lhs (map fst bargs_pre) (map fst (bargs_post))
965+ . rhs_trans info
966+ mapM_ (rec_elabDecl info EAll (info { rhs_trans = rhstrans' })) wb
963967
964968 -- rhs becomes: fname' ps_pre wval ps_post Refl
965969 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)
10011005 getImps _ = []
10021006
10031007 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
10051009 return $ PClauses fc o wname cs'
1006− | otherwise = ifail $ show fc ++ "with clause uses wrong function name " ++ show n
10071010 mkAuxC pn wname lhs ns ns' d = return $ d
10081011
10091012 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)
10341037 addArg (PApp fc f args) w = PApp fc f (args ++ [pexp w])
10351038 addArg (PRef fc hls f) w = PApp fc (PRef fc hls f) [pexp w]
10361039
1040+ -- ns, arguments which don't depend on the with argument
1041+ -- ns', arguments which do
10371042 updateLHS n pn wname mvars ns_in ns_in' (PApp fc (PRef fc' hls' n') args) w
10381043 = let ns = map (keepMvar (map fst mvars) fc') ns_in
10391044 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)
10461051 updateLHS n pn wname mvars ns_in ns_in' tm w
10471052 = updateLHS n pn wname mvars ns_in ns_in' (PApp fc tm []) w
10481053
1054+ -- Only keep a var as a pattern variable in the with block if it's
1055+ -- matched in the top level pattern
10491056 keepMvar mvs fc v | v `elem` mvs = PRef fc [] v
10501057 | otherwise = Placeholder
10511058
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
1062+ where
1063+ arity (PApp _ _ as) = length as
1064+ arity _ = 0
1065+
1066+ lhs_arity = arity toplhs
1067+
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"))
1071+ Right mvars ->
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') ++
1078+ case pn of
1079+ Nothing -> []
1080+ Just pnm -> [pexp (PRef fc [] pnm)]) in
1081+ case wty of
1082+ Nothing -> res -- can't happen!
1083+ Just ty -> addResolves ty res
1084+ updateApp tm = tm
1085+
1086+ addResolves ty (PApp fc f args) = PApp fc f (addResolvesArgs fc ty args)
1087+ addResolves ty tm = tm
1088+
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
1103+
10521104 fullApp (PApp _ (PApp fc f args) xs) = fullApp (PApp fc f (args ++ xs))
10531105 fullApp x = x
10541106
@@ -1059,3 +1111,19 @@ elabClause info opts (_, PWith fc fname lhs_in withs wval_in pn_in withblock)
10591111 split deps [] pre = (reverse pre, [])
10601112
10611113 abstract wn wv wty (n, argty) = (n, substTerm wv (P Bound wn wty) argty)
1114+
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)
1125+
1126+mapRHSdecl :: (PTerm -> PTerm) -> PDecl -> PDecl
1127+mapRHSdecl f (PClauses fc opt n cs)
1128+ = PClauses fc opt n (map (mapRHS f) cs)
1129+mapRHSdecl f t = t