From e108b3c6dac6d1440e2b754f3807aadb3a609b02 Mon Sep 17 00:00:00 2001 From: Andrei Borzenkov Date: Wed, 23 Oct 2024 13:21:21 +0400 Subject: [PATCH] Eliminate tuple in map constructors --- src/PersistentOrderedMap.mo | 230 +++++++++++++++--------------- test/PersistentOrderedMap.test.mo | 10 +- 2 files changed, 120 insertions(+), 120 deletions(-) diff --git a/src/PersistentOrderedMap.mo b/src/PersistentOrderedMap.mo index 36699b8e..a4e310d0 100644 --- a/src/PersistentOrderedMap.mo +++ b/src/PersistentOrderedMap.mo @@ -42,8 +42,8 @@ module { /// The keys have the generic type `K` and the values the generic type `V`. /// Leaves are considered implicitly black. public type Map = { - #red : (Map, (K, V), Map); - #black : (Map, (K, V), Map); + #red : (Map, K, V, Map); + #black : (Map, K, V, Map); #leaf }; @@ -553,10 +553,10 @@ module { public func iter(rbMap : Map, direction : Direction) : I.Iter<(K, V)> { let turnLeftFirst : MapTraverser - = func (l, xy, r, ts) { ?(#tr(l), ?(#xy(xy), ?(#tr(r), ts))) }; + = func (l, x, y, r, ts) { ?(#tr(l), ?(#xy(x, y), ?(#tr(r), ts))) }; let turnRightFirst : MapTraverser - = func (l, xy, r, ts) { ?(#tr(r), ?(#xy(xy), ?(#tr(l), ts))) }; + = func (l, x, y, r, ts) { ?(#tr(r), ?(#xy(x, y), ?(#tr(l), ts))) }; switch direction { case (#fwd) IterMap(rbMap, turnLeftFirst); @@ -564,7 +564,7 @@ module { } }; - type MapTraverser = (Map, (K, V), Map, IterRep) -> IterRep; + type MapTraverser = (Map, K, V, Map, IterRep) -> IterRep; class IterMap(rbMap : Map, mapTraverser : MapTraverser) { var trees : IterRep = ?(#tr(rbMap), null); @@ -579,12 +579,12 @@ module { trees := ts; ?xy }; - case (?(#tr(#red(l, xy, r)), ts)) { - trees := mapTraverser(l, xy, r, ts); + case (?(#tr(#red(l, x, y, r)), ts)) { + trees := mapTraverser(l, x, y, r, ts); next() }; - case (?(#tr(#black(l, xy, r)), ts)) { - trees := mapTraverser(l, xy, r, ts); + case (?(#tr(#black(l, x, y, r)), ts)) { + trees := mapTraverser(l, x, y, r, ts); next() } } @@ -595,11 +595,11 @@ module { func mapRec(m : Map) : Map { switch m { case (#leaf) { #leaf }; - case (#red(l, xy, r)) { - #red(mapRec l, (xy.0, f xy), mapRec r) + case (#red(l, x, y, r)) { + #red(mapRec l, x, f(x,y), mapRec r) }; - case (#black(l, xy, r)) { - #black(mapRec l, (xy.0, f xy), mapRec r) + case (#black(l, x, y, r)) { + #black(mapRec l, x, f(x, y), mapRec r) }; } }; @@ -614,12 +614,12 @@ module { { switch (rbMap) { case (#leaf) { base }; - case (#red(l, (k, v), r)) { + case (#red(l, k, v, r)) { let left = foldLeft(l, base, combine); let middle = combine(k, v, left); foldLeft(r, middle, combine) }; - case (#black(l, (k, v), r)) { + case (#black(l, k, v, r)) { let left = foldLeft(l, base, combine); let middle = combine(k, v, left); foldLeft(r, middle, combine) @@ -635,12 +635,12 @@ module { { switch (rbMap) { case (#leaf) { base }; - case (#red(l, (k, v), r)) { + case (#red(l, k, v, r)) { let right = foldRight(r, base, combine); let middle = combine(k, v, right); foldRight(l, middle, combine) }; - case (#black(l, (k, v), r)) { + case (#black(l, k, v, r)) { let right = foldRight(r, base, combine); let middle = combine(k, v, right); foldRight(l, middle, combine) @@ -662,10 +662,10 @@ module { public func size(t : Map) : Nat { switch t { - case (#red(l, _, r)) { + case (#red(l, _, _, r)) { size(l) + size(r) + 1 }; - case (#black(l, _, r)) { + case (#black(l, _, _, r)) { size(l) + size(r) + 1 }; case (#leaf) { 0 } @@ -674,17 +674,17 @@ module { public func get(t : Map, compare : (K, K) -> O.Order, x : K) : ?V { switch t { - case (#red(l, xy, r)) { - switch (compare(x, xy.0)) { + case (#red(l, x1, y1, r)) { + switch (compare(x, x1)) { case (#less) { get(l, compare, x) }; - case (#equal) { ?xy.1 }; + case (#equal) { ?y1 }; case (#greater) { get(r, compare, x) } } }; - case (#black(l, xy, r)) { - switch (compare(x, xy.0)) { + case (#black(l, x1, y1, r)) { + switch (compare(x, x1)) { case (#less) { get(l, compare, x) }; - case (#equal) { ?xy.1 }; + case (#equal) { ?y1 }; case (#greater) { get(r, compare, x) } } }; @@ -694,8 +694,8 @@ module { func redden(t : Map) : Map { switch t { - case (#black (l, xy, r)) { - (#red (l, xy, r)) + case (#black (l, x, y, r)) { + (#red (l, x, y, r)) }; case _ { Debug.trap "RBTree.red" @@ -703,42 +703,42 @@ module { } }; - func lbalance(left : Map, xy : (K,V), right : Map) : Map { + func lbalance(left : Map, x : K, y : V, right : Map) : Map { switch (left, right) { - case (#red(#red(l1, xy1, r1), xy2, r2), r) { + case (#red(#red(l1, x1, y1, r1), x2, y2, r2), r) { #red( - #black(l1, xy1, r1), - xy2, - #black(r2, xy, r)) + #black(l1, x1, y1, r1), + x2, y2, + #black(r2, x, y, r)) }; - case (#red(l1, xy1, #red(l2, xy2, r2)), r) { + case (#red(l1, x1, y1, #red(l2, x2, y2, r2)), r) { #red( - #black(l1, xy1, l2), - xy2, - #black(r2, xy, r)) + #black(l1, x1, y1, l2), + x2, y2, + #black(r2, x, y, r)) }; case _ { - #black(left, xy, right) + #black(left, x, y, right) } } }; - func rbalance(left : Map, xy : (K,V), right : Map) : Map { + func rbalance(left : Map, x : K, y : V, right : Map) : Map { switch (left, right) { - case (l, #red(l1, xy1, #red(l2, xy2, r2))) { + case (l, #red(l1, x1, y1, #red(l2, x2, y2, r2))) { #red( - #black(l, xy, l1), - xy1, - #black(l2, xy2, r2)) + #black(l, x, y, l1), + x1, y1, + #black(l2, x2, y2, r2)) }; - case (l, #red(#red(l1, xy1, r1), xy2, r2)) { + case (l, #red(#red(l1, x1, y1, r1), x2, y2, r2)) { #red( - #black(l, xy, l1), - xy1, - #black(r1, xy2, r2)) + #black(l, x, y, l1), + x1, y1, + #black(r1, x2, y2, r2)) }; case _ { - #black(left, xy, right) + #black(left, x, y, right) }; } }; @@ -755,42 +755,42 @@ module { : Map{ func ins(tree : Map) : Map { switch tree { - case (#black(left, xy, right)) { - switch (compare (key, xy.0)) { + case (#black(left, x, y, right)) { + switch (compare (key, x)) { case (#less) { - lbalance(ins left, xy, right) + lbalance(ins left, x, y, right) }; case (#greater) { - rbalance(left, xy, ins right) + rbalance(left, x, y, ins right) }; case (#equal) { - let newVal = onClash({ new = val; old = xy.1 }); - #black(left, (key,newVal), right) + let newVal = onClash({ new = val; old = y }); + #black(left, key, newVal, right) } } }; - case (#red(left, xy, right)) { - switch (compare (key, xy.0)) { + case (#red(left, x, y, right)) { + switch (compare (key, x)) { case (#less) { - #red(ins left, xy, right) + #red(ins left, x, y, right) }; case (#greater) { - #red(left, xy, ins right) + #red(left, x, y, ins right) }; case (#equal) { - let newVal = onClash { new = val; old = xy.1 }; - #red(left, (key,newVal), right) + let newVal = onClash { new = val; old = y }; + #red(left, key, newVal, right) } } }; case (#leaf) { - #red(#leaf, (key,val), #leaf) + #red(#leaf, key, val, #leaf) } }; }; switch (ins m) { - case (#red(left, xy, right)) { - #black(left, xy, right); + case (#red(left, x, y, right)) { + #black(left, x, y, right); }; case other { other }; }; @@ -821,43 +821,43 @@ module { ) : Map = replace(m, compare, key, val).0; - func balLeft(left : Map, xy : (K,V), right : Map) : Map { + func balLeft(left : Map, x : K, y : V, right : Map) : Map { switch (left, right) { - case (#red(l1, xy1, r1), r) { + case (#red(l1, x1, y1, r1), r) { #red( - #black(l1, xy1, r1), - xy, + #black(l1, x1, y1, r1), + x, y, r) }; - case (_, #black(l2, xy2, r2)) { - rbalance(left, xy, #red(l2, xy2, r2)) + case (_, #black(l2, x2, y2, r2)) { + rbalance(left, x, y, #red(l2, x2, y2, r2)) }; - case (_, #red(#black(l2, xy2, r2), xy3, r3)) { + case (_, #red(#black(l2, x2, y2, r2), x3, y3, r3)) { #red( - #black(left, xy, l2), - xy2, - rbalance(r2, xy3, redden r3)) + #black(left, x, y, l2), + x2, y2, + rbalance(r2, x3, y3, redden r3)) }; case _ { Debug.trap "balLeft" }; } }; - func balRight(left : Map, xy : (K,V), right : Map) : Map { + func balRight(left : Map, x : K, y : V, right : Map) : Map { switch (left, right) { - case (l, #red(l1, xy1, r1)) { + case (l, #red(l1, x1, y1, r1)) { #red( l, - xy, - #black(l1, xy1, r1)) + x, y, + #black(l1, x1, y1, r1)) }; - case (#black(l1, xy1, r1), r) { - lbalance(#red(l1, xy1, r1), xy, r); + case (#black(l1, x1, y1, r1), r) { + lbalance(#red(l1, x1, y1, r1), x, y, r); }; - case (#red(l1, xy1, #black(l2, xy2, r2)), r3) { + case (#red(l1, x1, y1, #black(l2, x2, y2, r2)), r3) { #red( - lbalance(redden l1, xy1, l2), - xy2, - #black(r2, xy, r3)) + lbalance(redden l1, x1, y1, l2), + x2, y2, + #black(r2, x, y, r3)) }; case _ { Debug.trap "balRight" }; } @@ -867,39 +867,39 @@ module { switch (left, right) { case (#leaf, _) { right }; case (_, #leaf) { left }; - case (#red (l1, xy1, r1), - #red (l2, xy2, r2)) { + case (#red (l1, x1, y1, r1), + #red (l2, x2, y2, r2)) { switch (append (r1, l2)) { - case (#red (l3, xy3, r3)) { + case (#red (l3, x3, y3, r3)) { #red( - #red(l1, xy1, l3), - xy3, - #red(r3, xy2, r2)) + #red(l1, x1, y1, l3), + x3, y3, + #red(r3, x2, y2, r2)) }; case r1l2 { - #red(l1, xy1, #red(r1l2, xy2, r2)) + #red(l1, x1, y1, #red(r1l2, x2, y2, r2)) } } }; - case (t1, #red(l2, xy2, r2)) { - #red(append(t1, l2), xy2, r2) + case (t1, #red(l2, x2, y2, r2)) { + #red(append(t1, l2), x2, y2, r2) }; - case (#red(l1, xy1, r1), t2) { - #red(l1, xy1, append(r1, t2)) + case (#red(l1, x1, y1, r1), t2) { + #red(l1, x1, y1, append(r1, t2)) }; - case (#black(l1, xy1, r1), #black (l2, xy2, r2)) { + case (#black(l1, x1, y1, r1), #black (l2, x2, y2, r2)) { switch (append (r1, l2)) { - case (#red (l3, xy3, r3)) { + case (#red (l3, x3, y3, r3)) { #red( - #black(l1, xy1, l3), - xy3, - #black(r3, xy2, r2)) + #black(l1, x1, y1, l3), + x3, y3, + #black(r3, x2, y2, r2)) }; case r1l2 { balLeft ( l1, - xy1, - #black(r1l2, xy2, r2) + x1, y1, + #black(r1l2, x2, y2, r2) ) } } @@ -912,43 +912,43 @@ module { public func remove(tree : Map, compare : (K, K) -> O.Order, x : K) : (Map, ?V) { var y0 : ?V = null; - func delNode(left : Map, xy : (K, V), right : Map) : Map { - switch (compare (x, xy.0)) { + func delNode(left : Map, x1 : K, y1 : V, right : Map) : Map { + switch (compare (x, x1)) { case (#less) { let newLeft = del left; switch left { - case (#black(_, _, _)) { - balLeft(newLeft, xy, right) + case (#black(_, _, _, _)) { + balLeft(newLeft, x1, y1, right) }; case _ { - #red(newLeft, xy, right) + #red(newLeft, x1, y1, right) } } }; case (#greater) { let newRight = del right; switch right { - case (#black(_, _, _)) { - balRight(left, xy, newRight) + case (#black(_, _, _, _)) { + balRight(left, x1, y1, newRight) }; case _ { - #red(left, xy, newRight) + #red(left, x1, y1, newRight) } } }; case (#equal) { - y0 := ?xy.1; + y0 := ?y1; append(left, right) }; } }; func del(tree : Map) : Map { switch tree { - case (#red(left, xy, right)) { - delNode(left, xy, right) + case (#red(left, x, y, right)) { + delNode(left, x, y, right) }; - case (#black(left, xy, right)) { - delNode(left, xy, right) + case (#black(left, x, y, right)) { + delNode(left, x, y, right) }; case (#leaf) { tree @@ -956,8 +956,8 @@ module { }; }; switch (del(tree)) { - case (#red(left, xy, right)) { - (#black(left, xy, right), y0); + case (#red(left, x, y, right)) { + (#black(left, x, y, right), y0); }; case other { (other, y0) }; }; diff --git a/test/PersistentOrderedMap.test.mo b/test/PersistentOrderedMap.test.mo index 4c78c618..adcf9799 100644 --- a/test/PersistentOrderedMap.test.mo +++ b/test/PersistentOrderedMap.test.mo @@ -41,13 +41,13 @@ func blackDepth(node : Map.Map) : Nat { }; switch node { case (#leaf) 0; - case (#red(left, (key, _), right)) { + case (#red(left, key, _, right)) { let leftBlacks = checkNode(left, key, right); assert (not isRed(left)); assert (not isRed(right)); leftBlacks }; - case (#black(left, (key, _), right)) { + case (#black(left, key, _, right)) { checkNode(left, key, right) + 1 } } @@ -56,7 +56,7 @@ func blackDepth(node : Map.Map) : Nat { func isRed(node : Map.Map) : Bool { switch node { - case (#red(_, _, _)) true; + case (#red(_, _, _, _)) true; case _ false } }; @@ -64,10 +64,10 @@ func isRed(node : Map.Map) : Bool { func checkKey(node : Map.Map, isValid : Nat -> Bool) { switch node { case (#leaf) {}; - case (#red( _, (key, _), _)) { + case (#red( _, key, _, _)) { assert (isValid(key)) }; - case (#black( _, (key, _), _)) { + case (#black( _, key, _, _)) { assert (isValid(key)) } }