Mercurial > urweb
changeset 1304:f0afe61a6f8b
Tweaking unification fix to apply to demo/more
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sun, 10 Oct 2010 15:37:14 -0400 |
parents | c7b9a33c26c8 |
children | a6fc03d28170 |
files | demo/more/dbgrid.ur demo/more/dlist.ur demo/more/grid.ur demo/more/grid0.ur demo/more/orm.ur lib/ur/string.ur src/elaborate.sml |
diffstat | 7 files changed, 86 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/demo/more/dbgrid.ur Sun Oct 10 14:41:03 2010 -0400 +++ b/demo/more/dbgrid.ur Sun Oct 10 15:37:14 2010 -0400 @@ -38,7 +38,7 @@ NonNull of metaBase (actual, input, filter) * metaBase (option actual, input, filter) | Nullable of metaBase (actual, input, filter) - con meta = fn global_actual_input_filter :: (Type * Type * Type * Type) => + con meta = fn global_actual_input_filter => {Initialize : transaction global_actual_input_filter.1, Handlers : global_actual_input_filter.1 -> metaBoth global_actual_input_filter.2 global_actual_input_filter.3 @@ -48,25 +48,26 @@ fun editable [ts] [rest] [nm :: Name] [[nm] ~ rest] name (m : meta ts) : colMeta ([nm = ts.2] ++ rest) (editableState ts) = let - fun doMr mr = {Header = name, - Project = fn r => mr.Initialize r.nm, - Update = fn r s => - vo <- current (mr.Parse s); - return (case vo of - None => r - | Some v => r -- nm ++ {nm = v}), - Display = mr.Display, - Edit = mr.Edit, - Validate = fn s => vo <- mr.Parse s; return (Option.isSome vo), - CreateFilter = mr.CreateFilter, - DisplayFilter = mr.DisplayFilter, - Filter = fn i r => mr.Filter i r.nm, - Sort = Some (fn r1 r2 => mr.Sort r1.nm r2.nm)} + fun doMr (mr : metaBase (ts.2, ts.3, ts.4)) : colMeta' ([nm = ts.2] ++ rest) ts.3 ts.4 = + {Header = name, + Project = fn r => mr.Initialize r.nm, + Update = fn r s => + vo <- current (mr.Parse s); + return (case vo of + None => r + | Some v => r -- nm ++ {nm = v}), + Display = mr.Display, + Edit = mr.Edit, + Validate = fn s => vo <- mr.Parse s; return (Option.isSome vo), + CreateFilter = mr.CreateFilter, + DisplayFilter = mr.DisplayFilter, + Filter = fn i r => mr.Filter i r.nm, + Sort = Some (fn r1 r2 => mr.Sort r1.nm r2.nm)} in {Initialize = m.Initialize, Handlers = fn data => case m.Handlers data of - NonNull (mr, _) => doMr mr - | Nullable mr => doMr mr} + NonNull (mr, _) => doMr mr + | Nullable mr => doMr mr} end con readOnlyState (ts :: (Type * Type * Type * Type)) = (ts.1, ts.3, ts.4)
--- a/demo/more/dlist.ur Sun Oct 10 14:41:03 2010 -0400 +++ b/demo/more/dlist.ur Sun Oct 10 15:37:14 2010 -0400 @@ -119,7 +119,8 @@ end}/> </xml> -fun renderFlat [ctx] [ctx ~ body] [t] (f : t -> position -> xml (ctx ++ body) [] []) filter = +fun renderFlat [ctx] [ctx ~ body] [t] (f : t -> position -> xml (ctx ++ body) [] []) + : option int -> list (t * position) -> xml (ctx ++ body) [] [] = let fun renderFlat' len ls = case len of @@ -233,13 +234,13 @@ None => elems | Some pos => skip pos elems in - return (renderFlat f r.Filter len elems) + return (renderFlat f len elems) end}/> </xml> fun delete pos = pos -fun elements' [t] (dl'' : dlist'' t) = +fun elements' [t] (dl'' : dlist'' t) : signal (list t) = case dl'' of Nil => return [] | Cons (x, dl'') => @@ -247,13 +248,13 @@ tl <- elements' dl''; return (x :: tl) -fun elements [t] (dl : dlist t) = +fun elements [t] (dl : dlist t) : signal (list t) = dl' <- signal dl; case dl' of Empty => return [] | Nonempty {Head = hd, ...} => elements' hd -fun size' [t] (dl'' : dlist'' t) = +fun size' [t] (dl'' : dlist'' t) : signal int = case dl'' of Nil => return 0 | Cons (x, dl'') => @@ -261,13 +262,13 @@ n <- size' dl''; return (n + 1) -fun size [t] (dl : dlist t) = +fun size [t] (dl : dlist t) : signal int = dl' <- signal dl; case dl' of Empty => return 0 | Nonempty {Head = hd, ...} => size' hd -fun numPassing' [t] (f : t -> signal bool) (dl'' : dlist'' t) = +fun numPassing' [t] (f : t -> signal bool) (dl'' : dlist'' t) : signal int = case dl'' of Nil => return 0 | Cons (x, dl'') => @@ -276,7 +277,7 @@ n <- numPassing' f dl''; return (if b then n + 1 else n) -fun numPassing [t] (f : t -> signal bool) (dl : dlist t) = +fun numPassing [t] (f : t -> signal bool) (dl : dlist t) : signal int = dl' <- signal dl; case dl' of Empty => return 0
--- a/demo/more/grid.ur Sun Oct 10 14:41:03 2010 -0400 +++ b/demo/more/grid.ur Sun Oct 10 15:37:14 2010 -0400 @@ -49,16 +49,18 @@ fun make (row : M.row) [input] [filter] (m : colMeta' M.row input filter) : transaction input = m.Project row fun makeAll cols row = @@Monad.exec [transaction] _ [map snd3 M.cols] - (@map2 [fst3] [colMeta M.row] [fn p => transaction (snd3 p)] - (fn [p] data meta => make row(meta.Handlers data)) - M.folder cols M.cols) - (@@Folder.mp [_] [_] M.folder) + (@map2 [fst3] [colMeta M.row] [fn p => transaction (snd3 p)] + (fn [p] data meta => make row (meta.Handlers data)) + M.folder cols M.cols) + (@@Folder.mp [_] [_] M.folder) + + type listT = {Row : source M.row, + Cols : source ($(map snd3 M.cols)), + Updating : source bool, + Selected : source bool} type grid = {Cols : $(map fst3 M.cols), - Rows : Dlist.dlist {Row : source M.row, - Cols : source ($(map snd3 M.cols)), - Updating : source bool, - Selected : source bool}, + Rows : Dlist.dlist listT, Selection : source bool, Filters : $(map thd3 M.cols), Sort : source (option (M.row -> M.row -> bool)), @@ -250,11 +252,12 @@ return (f r1 r2)) f)} grid.Rows} - <dyn signal={rows <- Dlist.foldl (fn row => @Monad.mapR2 _ [aggregateMeta M.row] [id] [id] - (fn [nm :: Name] [t :: Type] meta acc => - Monad.mp (fn v => meta.Step v acc) - (signal row.Row)) - M.aggFolder M.aggregates) + <dyn signal={rows <- Dlist.foldl (fn row : listT => + @Monad.mapR2 _ [aggregateMeta M.row] [id] [id] + (fn [nm :: Name] [t :: Type] meta acc => + Monad.mp (fn v => meta.Step v acc) + (signal row.Row)) + M.aggFolder M.aggregates) (@mp [aggregateMeta M.row] [id] (fn [t] meta => meta.Initial) M.aggFolder M.aggregates) grid.Rows;
--- a/demo/more/grid0.ur Sun Oct 10 14:41:03 2010 -0400 +++ b/demo/more/grid0.ur Sun Oct 10 15:37:14 2010 -0400 @@ -13,8 +13,8 @@ A = {New = return 0, Inj = _}} - val cols = {Id = Direct.readOnly [#Id] ! "Id" Direct.int, - A = Direct.editable [#A] ! "A" Direct.int} + val cols = {Id = Direct.readOnly [#Id] "Id" Direct.int, + A = Direct.editable [#A] "A" Direct.int} val aggregates = {}
--- a/demo/more/orm.ur Sun Oct 10 14:41:03 2010 -0400 +++ b/demo/more/orm.ur Sun Oct 10 15:37:14 2010 -0400 @@ -1,13 +1,14 @@ con link = fn col_parent :: (Type * Type) => col_parent.1 -> transaction (option col_parent.2) -fun noParent [t ::: Type] (_ : t) = return None +fun noParent [t ::: Type] (_ : t) : transaction (option unit) = return None con meta = fn (col :: Type, parent :: Type) => { Link : link (col, parent), Inj : sql_injectable col } -fun local [t :: Type] (inj : sql_injectable t) = {Link = noParent, - Inj = inj} +fun local [t :: Type] (inj : sql_injectable t) : meta (t, unit) = + {Link = noParent, + Inj = inj} functor Table(M : sig con cols :: {(Type * Type)} @@ -31,19 +32,19 @@ val id = {Link = fn id => resultOut (SELECT * FROM t WHERE t.Id = {[id]}), Inj = inj} - fun ensql [avail] (r : row') : $(map (sql_exp avail [] []) fs') = + fun ensql [avail ::_] (r : row') : $(map (sql_exp avail [] []) fs') = @map2 [meta] [fst] [fn ts :: (Type * Type) => sql_exp avail [] [] ts.1] (fn [ts] meta v => @sql_inject meta.Inj v) M.folder M.cols r fun create (r : row') = id <- nextval s; - dml (insert t ({Id = sql_inject id} ++ ensql r)); + dml (insert t ({Id = sql_inject id} ++ ensql [[]] r)); return ({Id = id} ++ r) fun delete r = dml (DELETE FROM t WHERE t.Id = {[r.Id]}) - fun save r = dml (update [fs'] (ensql (r -- #Id)) t (WHERE T.Id = {[r.Id]})) + fun save r = dml (update [fs'] (ensql [[T = [Id = int] ++ map fst M.cols]] (r -- #Id)) t (WHERE T.Id = {[r.Id]})) fun lookup id = ro <- oneOrNoRows (SELECT * FROM t WHERE t.Id = {[id]});
--- a/lib/ur/string.ur Sun Oct 10 14:41:03 2010 -0400 +++ b/lib/ur/string.ur Sun Oct 10 15:37:14 2010 -0400 @@ -57,7 +57,7 @@ mp' (length s - 1) "" end -fun newlines [ctx] [[Body] ~ ctx] s : xml ([Body] ++ ctx) [] [] = +fun newlines [ctx] [[Body] ~ ctx] (s : string) : xml ([Body] ++ ctx) [] [] = case split s #"\n" of None => cdata s | Some (s1, s2) => <xml>{[s1]}<br/>{newlines s2}</xml>
--- a/src/elaborate.sml Sun Oct 10 14:41:03 2010 -0400 +++ b/src/elaborate.sml Sun Oct 10 15:37:14 2010 -0400 @@ -655,6 +655,24 @@ val delayedExhaustives = ref ([] : (E.env * L'.con * L'.pat list * ErrorMsg.span) list) + exception CantSquish + + fun squish by = + U.Con.mapB {kind = fn _ => fn k => k, + con = fn bound => fn c => + case c of + L'.CRel xn => + if xn < bound then + c + else if bound <= xn andalso xn < bound + by then + raise CantSquish + else + L'.CRel (xn - by) + | L'.CUnif _ => raise CantSquish + | _ => c, + bind = fn (bound, U.Con.RelC _) => bound + 1 + | (bound, _) => bound} 0 + fun unifyRecordCons env (loc, c1, c2) = let fun rkindof c = @@ -1056,6 +1074,19 @@ else r := SOME c1All + | (L'.CUnif (nl, _, _, _, r), _) => + if occursCon r c2All then + err COccursCheckFailed + else + (r := SOME (squish nl c2All) + handle CantSquish => err CIncompatible) + | (_, L'.CUnif (nl, _, _, _, r)) => + if occursCon r c1All then + err COccursCheckFailed + else + (r := SOME (squish nl c1All) + handle CantSquish => err CIncompatible) + | (L'.CUnit, L'.CUnit) => () | (L'.TFun (d1, r1), L'.TFun (d2, r2)) => @@ -1290,7 +1321,8 @@ val k = (L'.KType, loc) val unifs = map (fn _ => cunif (loc, k)) xs val nxs = length unifs - 1 - val t = ListUtil.foldli (fn (i, u, t) => subConInCon env (nxs - i, u) t) t unifs + val t = ListUtil.foldli (fn (i, u, t) => subConInCon env (nxs - i, + E.mliftConInCon (nxs - i) u) t) t unifs val dn = foldl (fn (u, dn) => (L'.CApp (dn, u), loc)) dn unifs in ignore (checkPatCon env p' pt t);