# HG changeset patch # User Adam Chlipala # Date 1262300873 18000 # Node ID 52571ca9b7770184e0a7173f19f50c7ed6ef09be # Parent c9137606733a9544cf87e81f7be29724d19d4f99 Eta-expand bodies of transaction functions in Monoization, to enable later optimization diff -r c9137606733a -r 52571ca9b777 lib/ur/list.ur --- a/lib/ur/list.ur Thu Dec 31 16:12:13 2009 -0500 +++ b/lib/ur/list.ur Thu Dec 31 18:07:53 2009 -0500 @@ -133,6 +133,20 @@ mapM' [] end +fun mapPartialM [m ::: (Type -> Type)] (_ : monad m) [a] [b] f = + let + fun mapPartialM' acc ls = + case ls of + [] => return (rev acc) + | x :: ls => + v <- f x; + mapPartialM' (case v of + None => acc + | Some x' => x' :: acc) ls + in + mapPartialM' [] + end + fun mapXM [m ::: (Type -> Type)] (_ : monad m) [a] [ctx ::: {Unit}] f = let fun mapXM' ls = @@ -237,6 +251,25 @@ []; return (rev ls) +fun mapQueryM [tables ::: {{Type}}] [exps ::: {Type}] [t ::: Type] + [tables ~ exps] (q : sql_query tables exps) + (f : $(exps ++ map (fn fields :: {Type} => $fields) tables) -> transaction t) = + ls <- query q + (fn fs acc => v <- f fs; return (v :: acc)) + []; + return (rev ls) + +fun mapQueryPartialM [tables ::: {{Type}}] [exps ::: {Type}] [t ::: Type] + [tables ~ exps] (q : sql_query tables exps) + (f : $(exps ++ map (fn fields :: {Type} => $fields) tables) -> transaction (option t)) = + ls <- query q + (fn fs acc => v <- f fs; + return (case v of + None => acc + | Some v => v :: acc)) + []; + return (rev ls) + fun assoc [a] [b] (_ : eq a) (x : a) = let fun assoc' (ls : list (a * b)) = diff -r c9137606733a -r 52571ca9b777 lib/ur/list.urs --- a/lib/ur/list.urs Thu Dec 31 16:12:13 2009 -0500 +++ b/lib/ur/list.urs Thu Dec 31 18:07:53 2009 -0500 @@ -27,6 +27,8 @@ val mapM : m ::: (Type -> Type) -> monad m -> a ::: Type -> b ::: Type -> (a -> m b) -> t a -> m (t b) +val mapPartialM : m ::: (Type -> Type) -> monad m -> a ::: Type -> b ::: Type -> (a -> m (option b)) -> t a -> m (t b) + val mapXM : m ::: (Type -> Type) -> monad m -> a ::: Type -> ctx ::: {Unit} -> (a -> m (xml ctx [] [])) -> t a -> m (xml ctx [] []) @@ -53,6 +55,18 @@ -> ($(exps ++ map (fn fields :: {Type} => $fields) tables) -> t) -> transaction (list t) +val mapQueryM : tables ::: {{Type}} -> exps ::: {Type} -> t ::: Type + -> [tables ~ exps] => + sql_query tables exps + -> ($(exps ++ map (fn fields :: {Type} => $fields) tables) -> transaction t) + -> transaction (list t) + +val mapQueryPartialM : tables ::: {{Type}} -> exps ::: {Type} -> t ::: Type + -> [tables ~ exps] => + sql_query tables exps + -> ($(exps ++ map (fn fields :: {Type} => $fields) tables) -> transaction (option t)) + -> transaction (list t) + (** Association lists *) val assoc : a ::: Type -> b ::: Type -> eq a -> a -> t (a * b) -> option b diff -r c9137606733a -r 52571ca9b777 src/mono_print.sml --- a/src/mono_print.sml Thu Dec 31 16:12:13 2009 -0500 +++ b/src/mono_print.sml Thu Dec 31 18:07:53 2009 -0500 @@ -206,18 +206,26 @@ string ".", string x] - | ECase (e, pes, _) => parenIf true (box [string "case", - space, - p_exp env e, - space, - string "of", - space, - p_list_sep (box [space, string "|", space]) - (fn (p, e) => box [p_pat env p, - space, - string "=>", - space, - p_exp (E.patBinds env p) e]) pes]) + | ECase (e, pes, {result, ...}) => parenIf true (box [string "case", + space, + p_exp env e, + space, + if !debug then + box [string "return", + space, + p_typ env result, + space] + else + box [], + string "of", + space, + p_list_sep (box [space, string "|", space]) + (fn (p, e) => box [p_pat env p, + space, + string "=>", + space, + p_exp (E.patBinds env p) e]) + pes]) | EError (e, t) => box [string "(error", space, diff -r c9137606733a -r 52571ca9b777 src/mono_reduce.sml --- a/src/mono_reduce.sml Thu Dec 31 16:12:13 2009 -0500 +++ b/src/mono_reduce.sml Thu Dec 31 18:07:53 2009 -0500 @@ -582,23 +582,22 @@ fun push () = case result of (TFun (dom, result), loc) => - if List.all (fn (_, (EAbs _, _)) => true | _ => false) pes then - let - val r = - EAbs ("y", dom, result, - (ECase (liftExpInExp 0 e', - map (fn (p, (EAbs (_, _, _, e), _)) => - (p, swapExpVarsPat (0, patBinds p) e) - | _ => raise Fail "MonoReduce ECase") pes, - {disc = disc, result = result}), loc)) - in - (*Print.prefaces "Swapped" - [("e", MonoPrint.p_exp env (e, ErrorMsg.dummySpan)), - ("r", MonoPrint.p_exp env (r, ErrorMsg.dummySpan))];*) - r - end - else - e + let + fun safe (e, _) = + case e of + EAbs _ => true + | _ => false + in + if List.all (safe o #2) pes then + EAbs ("y", dom, result, + (ECase (liftExpInExp 0 e', + map (fn (p, (EAbs (_, _, _, e), _)) => + (p, swapExpVarsPat (0, patBinds p) e) + | _ => raise Fail "MonoReduce ECase") pes, + {disc = disc, result = result}), loc)) + else + e + end | _ => e fun search pes = diff -r c9137606733a -r 52571ca9b777 src/monoize.sml --- a/src/monoize.sml Thu Dec 31 16:12:13 2009 -0500 +++ b/src/monoize.sml Thu Dec 31 18:07:53 2009 -0500 @@ -3440,6 +3440,29 @@ end | L.DValRec vis => let + val vis = map (fn (x, n, t, e, s) => + let + fun maybeTransaction (t, e) = + case (#1 t, #1 e) of + (L.CApp ((L.CFfi ("Basis", "transaction"), _), _), _) => + SOME (L.EAbs ("_", + (L.TRecord (L.CRecord ((L.KType, loc), []), loc), loc), + t, + (L.EApp (CoreEnv.liftExpInExp 0 e, + (L.ERecord [], loc)), loc)), loc) + | (L.TFun (dom, ran), L.EAbs (x, _, _, e)) => + (case maybeTransaction (ran, e) of + NONE => NONE + | SOME e => SOME (L.EAbs (x, dom, ran, e), loc)) + | _ => NONE + in + (x, n, t, + case maybeTransaction (t, e) of + NONE => e + | SOME e => e, + s) + end) vis + val env = foldl (fn ((x, n, t, e, s), env) => Env.pushENamed env x n t NONE s) env vis val (vis, fm) = ListUtil.foldlMap