From e30d6127f4fbd67a222c543804ba6b611b32d89b Mon Sep 17 00:00:00 2001 From: Ethan Sattler Date: Tue, 3 Oct 2017 03:15:38 -0400 Subject: [PATCH 1/4] Added `map-like` and `filter-like` methods and functions to the sets library. --- src/arr/trove/sets.arr | 28 ++- tests/pyret/tests/test-sets.arr | 370 +++++++++++++++++++++----------- 2 files changed, 271 insertions(+), 127 deletions(-) diff --git a/src/arr/trove/sets.arr b/src/arr/trove/sets.arr index ffcde1acbc..6ea0866ef9 100644 --- a/src/arr/trove/sets.arr +++ b/src/arr/trove/sets.arr @@ -12,7 +12,9 @@ provide { list-to-tree-set: list-to-tree-set, fold: set-fold, all: set-all, - any: set-any + any: set-any, + map-like: set-map-like, + filter-like: set-filter-like } end provide-types * @@ -367,6 +369,14 @@ data Set: method any(self, f) -> Boolean: self.elems.any(f) + end, + + method map-like(self, f) -> Set: + list-to-list-set(self.to-list().map(f)) + end, + + method filter-like(self, f) -> Set: + list-to-list-set(self.to-list().filter(f)) end | tree-set(elems :: AVLTree) with: @@ -436,6 +446,14 @@ data Set: method any(self, f) -> Boolean: self.elems.any(f) + end, + + method map-like(self, f) -> Set: + list-to-tree-set(self.to-list().map(f)) + end, + + method filter-like(self, f) -> Set: + list-to-tree-set(self.to-list().filter(f)) end sharing: @@ -589,6 +607,14 @@ fun list-to-tree(lst :: lists.List): end end +fun set-map-like(s :: Set, f :: (T -> U)) -> Set: + s.map-like(f) +end + +fun set-filter-like(f :: (T -> Boolean), s :: Set) -> Set: + s.filter-like(f) +end + fun arr-to-list-set(arr :: RawArray) -> Set: for raw-array-fold(ls from list-set(empty), elt from arr, _ from 0): ls.add(elt) diff --git a/tests/pyret/tests/test-sets.arr b/tests/pyret/tests/test-sets.arr index dd6d4a370c..cbb336a373 100644 --- a/tests/pyret/tests/test-sets.arr +++ b/tests/pyret/tests/test-sets.arr @@ -1,171 +1,289 @@ import pick as P check "regression for small constructors": - [set: 1, 2, 1].member(2) is true + [set: 1, 2, 1].member(2) is true - [set: 1, 2, 3, 2].member(3) is true - [set: 1, 2, 3, 3].member(3) is true - [set: 1, 2, 3, 2].member(2) is true - [set: 1, 2, 3, 4].member(3) is true - [set: 1, 2, 3, 2].member(5) is false + [set: 1, 2, 3, 2].member(3) is true + [set: 1, 2, 3, 3].member(3) is true + [set: 1, 2, 3, 2].member(2) is true + [set: 1, 2, 3, 4].member(3) is true + [set: 1, 2, 3, 2].member(5) is false - [set: 1, 2, 1, 3].member(2) is true - [set: 1, 2, 1, 3, 4].member(2) is true + [set: 1, 2, 1, 3].member(2) is true + [set: 1, 2, 1, 3, 4].member(2) is true end check "member": - [tree-set: 1, 2, 3].member(2) is true - [tree-set: 1, 2, 3].member(4) is false + [tree-set: 1, 2, 3].member(2) is true + [tree-set: 1, 2, 3].member(4) is false end check "add": - [tree-set: ].add(1) is [tree-set: 1] - [tree-set: 1].add(1) is [tree-set: 1] - [tree-set: 1, 2, 3].add(2) is [tree-set: 1, 2, 3] - [tree-set: 1, 2, 3].add(1.5) is [tree-set: 1, 2, 3, 1.5] + [tree-set: ].add(1) is [tree-set: 1] + [tree-set: 1].add(1) is [tree-set: 1] + [tree-set: 1, 2, 3].add(2) is [tree-set: 1, 2, 3] + [tree-set: 1, 2, 3].add(1.5) is [tree-set: 1, 2, 3, 1.5] end check "remove": - [tree-set: 1, 2].remove(18) is [tree-set: 1, 2] - [tree-set: 1, 2].remove(2) is [tree-set: 1] + [tree-set: 1, 2].remove(18) is [tree-set: 1, 2] + [tree-set: 1, 2].remove(2) is [tree-set: 1] end check "to-list": - [tree-set: 3, 1, 2].to-list() is [list: 1, 2, 3] - [tree-set: "x", "f"].to-list() is [tree-set: "f", "x"].to-list() - [tree-set: "x", "x"].to-list() is [tree-set: "x"].to-list() + [tree-set: 3, 1, 2].to-list() is [list: 1, 2, 3] + [tree-set: "x", "f"].to-list() is [tree-set: "f", "x"].to-list() + [tree-set: "x", "x"].to-list() is [tree-set: "x"].to-list() end fun raw-build-array(n, make-elt): - arr = raw-array-of(0, n) - for raw-array-fold(_ from 0, _ from arr, ix from 0): - raw-array-set(arr, ix, make-elt(n)) - end + arr = raw-array-of(0, n) + for raw-array-fold(_ from 0, _ from arr, ix from 0): + raw-array-set(arr, ix, make-elt(n)) + end end fun make-arraynge(n): - arr = raw-array-of(0, n) - for raw-array-fold(_ from 0, _ from arr, ix from 0): - raw-array-set(arr, ix, ix) - end + arr = raw-array-of(0, n) + for raw-array-fold(_ from 0, _ from arr, ix from 0): + raw-array-set(arr, ix, ix) + end end fun check-random-adds(n :: Number, set-constructor) -> Boolean: - nums = raw-build-array(n, lam(n2): random(n2 * n2) end) - expect = for raw-array-fold(s from [list: ], elt from nums, _ from 0): - if s.member(elt): s else: link(elt, s) end - end.sort() - set-constructor.make(nums).to-list().sort() == expect + nums = raw-build-array(n, lam(n2): random(n2 * n2) end) + expect = for raw-array-fold(s from [list: ], elt from nums, _ from 0): + if s.member(elt): s else: link(elt, s) end + end.sort() + set-constructor.make(nums).to-list().sort() == expect end fun check-random-removes(n :: Number, set-constructor) -> Boolean: - nums = raw-build-array(n, lam(n2): random(2 * n2) end) - orig = make-arraynge(n) - nums-list = raw-array-to-list(nums) - expect = for raw-array-fold(lst from empty, elt from orig, _ from 0): - if not(nums-list.member(elt)): - link(elt, lst) - else: - lst - end - end.reverse() - result = for fold(s from set-constructor.make(orig), rem-elt from nums-list): - s.remove(rem-elt) - end.to-list().sort() - result == expect + nums = raw-build-array(n, lam(n2): random(2 * n2) end) + orig = make-arraynge(n) + nums-list = raw-array-to-list(nums) + expect = for raw-array-fold(lst from empty, elt from orig, _ from 0): + if not(nums-list.member(elt)): + link(elt, lst) + else: + lst + end + end.reverse() + result = for fold(s from set-constructor.make(orig), rem-elt from nums-list): + s.remove(rem-elt) + end.to-list().sort() + result == expect end check: - fun canonicalize(s): - s.to-list().sort() - end - c = canonicalize - fun test-constructor(s) block: + fun canonicalize(s): + s.to-list().sort() + end + c = canonicalize + fun test-constructor(s) block: # SKIP(wating for predicates/annotations) # Set(s([list: 1, 2])) is true # Set(s([list: ])) is true - [s: 1, 2, 3].member(2) is true - [s: 1, 2, 3].member(4) is false - [s: ].add(1) is [s: 1] - [s: 1].add(1) is [s: 1] - [s: 1, 2, 3].add(2) is [s: 1, 2, 3] - [s: 1, 2, 3].add(1.5) is [s: 1, 2, 3, 1.5] - [s: 1, 2].remove(18) is [s: 1, 2] - [s: 1, 2].remove(2) is [s: 1] - [s: 3, 1, 2].to-list().sort() is [list: 1, 2, 3] - [s: 1, 2].union([s: 2, 3]) is [s: 1, 2, 3] - [s: 1, 2].union([s: 4]) is [s: 1, 2, 4] - [s: 1, 2].intersect([s: 2, 3]) is [s: 2] - [s: 1, 2].intersect([s: 4]) is [s: ] - [s: 1, 2].difference([s: 2, 3]) is [s: 1] - [s: 1, 2].difference([s: 4]) is [s: 1, 2] - [s: 1, 2].symmetric-difference([s: 1, 2]) is [s: ] - c([s: 1, 2].symmetric-difference([s: 2, 3])) is c([s: 1, 3]) - c([s: 1, 2].symmetric-difference([s: 3, 4])) is c([s: 1, 2, 3, 4]) - ([s: 1, 2.1, 3] <> [s: 1, 2.2, 3]) is true - c([s: 1, 2, 4]) is c([s: 2, 1, 4]) - - for each(n from range(1,21)) block: - check-random-adds(n * 5, s) is true - check-random-removes(n * 5, s) is true - end - end + [s: 1, 2, 3].member(2) is true + [s: 1, 2, 3].member(4) is false + [s: ].add(1) is [s: 1] + [s: 1].add(1) is [s: 1] + [s: 1, 2, 3].add(2) is [s: 1, 2, 3] + [s: 1, 2, 3].add(1.5) is [s: 1, 2, 3, 1.5] + [s: 1, 2].remove(18) is [s: 1, 2] + [s: 1, 2].remove(2) is [s: 1] + [s: 3, 1, 2].to-list().sort() is [list: 1, 2, 3] + [s: 1, 2].union([s: 2, 3]) is [s: 1, 2, 3] + [s: 1, 2].union([s: 4]) is [s: 1, 2, 4] + [s: 1, 2].intersect([s: 2, 3]) is [s: 2] + [s: 1, 2].intersect([s: 4]) is [s: ] + [s: 1, 2].difference([s: 2, 3]) is [s: 1] + [s: 1, 2].difference([s: 4]) is [s: 1, 2] + [s: 1, 2].symmetric-difference([s: 1, 2]) is [s: ] + c([s: 1, 2].symmetric-difference([s: 2, 3])) is c([s: 1, 3]) + c([s: 1, 2].symmetric-difference([s: 3, 4])) is c([s: 1, 2, 3, 4]) + ([s: 1, 2.1, 3] <> [s: 1, 2.2, 3]) is true + c([s: 1, 2, 4]) is c([s: 2, 1, 4]) + + for each(n from range(1,21)) block: + check-random-adds(n * 5, s) is true + check-random-removes(n * 5, s) is true + end + end # test-constructor(set) - test-constructor(list-set) - test-constructor(tree-set) + test-constructor(list-set) + test-constructor(tree-set) end check "Different constructors should work well together": - fun canonicalize(s): - s.to-list().sort() - end - c = canonicalize - fun test-constructor(s-a, s-b) block: - [s-a: 1, 2].union([s-b: 2, 3]) is [s-a: 1, 2, 3] - [s-a: 1, 2].union([s-b: 4]) is [s-a: 1, 2, 4] - [s-a: 1, 2].intersect([s-b: 2, 3]) is [s-a: 2] - [s-a: 1, 2].intersect([s-b: 4]) is [s-a: ] - [s-a: 1, 2].difference([s-b: 2, 3]) is [s-a: 1] - [s-a: 1, 2].difference([s-b: 4]) is [s-a: 1, 2] - [s-a: 1, 2].symmetric-difference([s-b: 1, 2]) is [s-a: ] - c([s-a: 1, 2].symmetric-difference([s-b: 2, 3])) is c([s-a: 1, 3]) - c([s-a: 1, 2].symmetric-difference([s-b: 3, 4])) is c([s-a: 1, 2, 3, 4]) - ([s-a: 1, 2.1, 3] <> [s-b: 1, 2.2, 3]) is true - c([s-a: 1, 2, 4]) is c([s-b: 2, 1, 4]) - [s-a: 1, 2, 4].size() is 3 - [s-a: 1, 2, 4].size() is 3 - end - - test-constructor(list-set, tree-set) - test-constructor(tree-set, list-set) + fun canonicalize(s): + s.to-list().sort() + end + c = canonicalize + fun test-constructor(s-a, s-b) block: + [s-a: 1, 2].union([s-b: 2, 3]) is [s-a: 1, 2, 3] + [s-a: 1, 2].union([s-b: 4]) is [s-a: 1, 2, 4] + [s-a: 1, 2].intersect([s-b: 2, 3]) is [s-a: 2] + [s-a: 1, 2].intersect([s-b: 4]) is [s-a: ] + [s-a: 1, 2].difference([s-b: 2, 3]) is [s-a: 1] + [s-a: 1, 2].difference([s-b: 4]) is [s-a: 1, 2] + [s-a: 1, 2].symmetric-difference([s-b: 1, 2]) is [s-a: ] + c([s-a: 1, 2].symmetric-difference([s-b: 2, 3])) is c([s-a: 1, 3]) + c([s-a: 1, 2].symmetric-difference([s-b: 3, 4])) is c([s-a: 1, 2, 3, 4]) + ([s-a: 1, 2.1, 3] <> [s-b: 1, 2.2, 3]) is true + c([s-a: 1, 2, 4]) is c([s-b: 2, 1, 4]) + [s-a: 1, 2, 4].size() is 3 + [s-a: 1, 2, 4].size() is 3 + end + + test-constructor(list-set, tree-set) + test-constructor(tree-set, list-set) end check "pick on list sets doesn't repeat order": - s = [list-set: 1, 2, 3] - var found-diff = false - # This will fail every 2^100 times it is run, given that JS has a decent RNG - # and given the current sets implementation - for each(i from range(0, 100)): - when not(s.pick().elt == s.pick().elt): - found-diff := true - end - end - found-diff is true -end - -check "sets pick visits all elemeents": - - fun pick-sum(s): - cases(P.Pick) s.pick(): - | pick-none => 0 - | pick-some(elt, rest) => elt + pick-sum(rest) - end - end - - pick-sum([list-set: 1, 2, 3, 4]) is 10 - pick-sum([tree-set: 1, 2, 3, 4]) is 10 - pick-sum([list-set:]) is 0 - pick-sum([tree-set:]) is 0 + s = [list-set: 1, 2, 3] + var found-diff = false + # This will fail every 2^100 times it is run, given that JS has a decent RNG + # and given the current sets implementation + for each(i from range(0, 100)): + when not(s.pick().elt == s.pick().elt): + found-diff := true + end + end + found-diff is true +end + +check "sets pick visits all elements": + + fun pick-sum(s): + cases(P.Pick) s.pick(): + | pick-none => 0 + | pick-some(elt, rest) => elt + pick-sum(rest) + end + end + + pick-sum([list-set: 1, 2, 3, 4]) is 10 + pick-sum([tree-set: 1, 2, 3, 4]) is 10 + pick-sum([list-set:]) is 0 + pick-sum([tree-set:]) is 0 + +end + +check "Set map-like function": + + # Check empty sets: + sets.map-like(empty-list-set, lam(x): x + 1 end) is empty-list-set + + sets.map-like(empty-tree-set, lam(x): x + 1 end) is empty-tree-set + + # Other tests: + sets.map-like([list-set: 1, 2, 3, 4], lam(x): 1 end) + is [list-set: 1] + + sets.map-like([tree-set: 1, 2, 3, 4], lam(x): 1 end) + is [tree-set: 1] + + sets.map-like([list-set: 1, 2, 3, 4], lam(x): x + 1 end) + is [list-set: 5, 4, 3, 2] + + sets.map-like([tree-set: 1, 2, 3, 4], lam(x): x + 1 end) + is [tree-set: 5, 4, 3, 2] + + + # Number -> String mapping test: + test-string = "abcd" + + sets.map-like([list-set: 0, 1, 2, 3], + lam(x): + string-substring(test-string, x, x + 1) + end).to-list().sort() is [list: "a", "b", "c", "d"] + + sets.map-like([tree-set: 0, 1, 2, 3], + lam(x): + string-substring(test-string, x, x + 1) + end).to-list().sort() is [list: "a", "b", "c", "d"] + + + # String -> Number mapping test: + sets.map-like([list-set: "Arr", ",", "Hello", "Pyret", "mateys!"], string-length) + is [list-set: 1, 3, 7, 5] + + sets.map-like([tree-set: "Arr", ",", "Hello", "Pyret", "mateys!"],string-length) + is [tree-set: 1, 3, 7, 5] +end + +check "Set map-like method": + + # Check empty sets: + empty-list-set.map-like(lam(x): x + 1 end) is empty-list-set + + empty-tree-set.map-like(lam(x): x + 1 end) is empty-tree-set + + # Check map-like returns the same list type: + [list-set: 1, 2, 3, 4].map-like(lam(x): x end) + is [list-set: 1, 2, 3, 4] + + [tree-set: 1, 2, 3, 4].map-like(lam(x): x end) + is [tree-set: 1, 2, 3, 4] + + # Other tests: + [list-set: 1, 2, 3, 4].map-like(lam(x): 1 end) + is [list-set: 1] + + [list-set: 1, 2, 3, 4].map-like(lam(x): x + 1 end) + is [list-set: 5, 4, 3, 2] + + [tree-set: 1, 2, 3, 4].map-like(lam(x): x + 1 end) + is [tree-set: 5, 4, 3, 2] + + + # Number -> String mapping test: + test-string = "abcd" + + [list-set: 0, 1, 2, 3].map-like(lam(x): + string-substring(test-string, x, x + 1) + end).to-list().sort() is [list: "a", "b", "c", "d"] + + [tree-set: 0, 1, 2, 3].map-like(lam(x): + string-substring(test-string, x, x + 1) + end).to-list().sort() is [list: "a", "b", "c", "d"] + + # String -> Number mapping test: + [list-set: "Arr", ",", "Hello", "Pyret", "mateys!"].map-like(string-length) + is [list-set: 1, 3, 7, 5] + + [tree-set: "Arr", ",", "Hello", "Pyret", "mateys!"].map-like(string-length) + is [tree-set: 1, 3, 7, 5] +end + +check "Set filter-like function": + + sets.filter-like(lam(e): e > 5 end, [list-set: -1, 1]) is [list-set: ] + sets.filter-like(lam(e): e > 5 end, [tree-set: -1, 1]) is [tree-set: ] + + sets.filter-like(lam(e): e > 0 end, [list-set: -1, 1]) is [list-set: 1] + sets.filter-like(lam(e): e > 0 end, [tree-set: -1, 1]) is [tree-set: 1] + + sets.filter-like(lam(e): num-modulo(e, 2) == 0 end, + [list-set: 1, 2, 3, 4]) is [list-set: 2, 4] + + sets.filter-like(lam(e): num-modulo(e, 2) == 0 end, + [tree-set: 1, 2, 3, 4]) is [tree-set: 2, 4] +end + + +check "Set filter-like method": + + [list-set: -1, 1].filter-like(lam(e): e > 5 end) is [list-set: ] + [tree-set: -1, 1].filter-like(lam(e): e > 5 end) is [tree-set: ] + + [list-set: -1, 1].filter-like(lam(e): e > 0 end) is [list-set: 1] + [tree-set: -1, 1].filter-like(lam(e): e > 0 end) is [tree-set: 1] + + [list-set: 1, 2, 3, 4].filter-like(lam(e): num-modulo(e, 2) == 0 end) + is [list-set: 2, 4] + [tree-set: 1, 2, 3, 4].filter-like(lam(e): num-modulo(e, 2) == 0 end) + is [tree-set: 2, 4] end From 777b77d6db2d669af7cf1b3a5ae8f0cc5e607c97 Mon Sep 17 00:00:00 2001 From: Ethan Sattler Date: Tue, 3 Oct 2017 03:24:27 -0400 Subject: [PATCH 2/4] Replaced tabs with 2 spaces. --- tests/pyret/tests/test-sets.arr | 384 ++++++++++++++++---------------- 1 file changed, 192 insertions(+), 192 deletions(-) diff --git a/tests/pyret/tests/test-sets.arr b/tests/pyret/tests/test-sets.arr index cbb336a373..69523dcfd9 100644 --- a/tests/pyret/tests/test-sets.arr +++ b/tests/pyret/tests/test-sets.arr @@ -1,289 +1,289 @@ import pick as P check "regression for small constructors": - [set: 1, 2, 1].member(2) is true + [set: 1, 2, 1].member(2) is true - [set: 1, 2, 3, 2].member(3) is true - [set: 1, 2, 3, 3].member(3) is true - [set: 1, 2, 3, 2].member(2) is true - [set: 1, 2, 3, 4].member(3) is true - [set: 1, 2, 3, 2].member(5) is false + [set: 1, 2, 3, 2].member(3) is true + [set: 1, 2, 3, 3].member(3) is true + [set: 1, 2, 3, 2].member(2) is true + [set: 1, 2, 3, 4].member(3) is true + [set: 1, 2, 3, 2].member(5) is false - [set: 1, 2, 1, 3].member(2) is true - [set: 1, 2, 1, 3, 4].member(2) is true + [set: 1, 2, 1, 3].member(2) is true + [set: 1, 2, 1, 3, 4].member(2) is true end check "member": - [tree-set: 1, 2, 3].member(2) is true - [tree-set: 1, 2, 3].member(4) is false + [tree-set: 1, 2, 3].member(2) is true + [tree-set: 1, 2, 3].member(4) is false end check "add": - [tree-set: ].add(1) is [tree-set: 1] - [tree-set: 1].add(1) is [tree-set: 1] - [tree-set: 1, 2, 3].add(2) is [tree-set: 1, 2, 3] - [tree-set: 1, 2, 3].add(1.5) is [tree-set: 1, 2, 3, 1.5] + [tree-set: ].add(1) is [tree-set: 1] + [tree-set: 1].add(1) is [tree-set: 1] + [tree-set: 1, 2, 3].add(2) is [tree-set: 1, 2, 3] + [tree-set: 1, 2, 3].add(1.5) is [tree-set: 1, 2, 3, 1.5] end check "remove": - [tree-set: 1, 2].remove(18) is [tree-set: 1, 2] - [tree-set: 1, 2].remove(2) is [tree-set: 1] + [tree-set: 1, 2].remove(18) is [tree-set: 1, 2] + [tree-set: 1, 2].remove(2) is [tree-set: 1] end check "to-list": - [tree-set: 3, 1, 2].to-list() is [list: 1, 2, 3] - [tree-set: "x", "f"].to-list() is [tree-set: "f", "x"].to-list() - [tree-set: "x", "x"].to-list() is [tree-set: "x"].to-list() + [tree-set: 3, 1, 2].to-list() is [list: 1, 2, 3] + [tree-set: "x", "f"].to-list() is [tree-set: "f", "x"].to-list() + [tree-set: "x", "x"].to-list() is [tree-set: "x"].to-list() end fun raw-build-array(n, make-elt): - arr = raw-array-of(0, n) - for raw-array-fold(_ from 0, _ from arr, ix from 0): - raw-array-set(arr, ix, make-elt(n)) - end + arr = raw-array-of(0, n) + for raw-array-fold(_ from 0, _ from arr, ix from 0): + raw-array-set(arr, ix, make-elt(n)) + end end fun make-arraynge(n): - arr = raw-array-of(0, n) - for raw-array-fold(_ from 0, _ from arr, ix from 0): - raw-array-set(arr, ix, ix) - end + arr = raw-array-of(0, n) + for raw-array-fold(_ from 0, _ from arr, ix from 0): + raw-array-set(arr, ix, ix) + end end fun check-random-adds(n :: Number, set-constructor) -> Boolean: - nums = raw-build-array(n, lam(n2): random(n2 * n2) end) - expect = for raw-array-fold(s from [list: ], elt from nums, _ from 0): - if s.member(elt): s else: link(elt, s) end - end.sort() - set-constructor.make(nums).to-list().sort() == expect + nums = raw-build-array(n, lam(n2): random(n2 * n2) end) + expect = for raw-array-fold(s from [list: ], elt from nums, _ from 0): + if s.member(elt): s else: link(elt, s) end + end.sort() + set-constructor.make(nums).to-list().sort() == expect end fun check-random-removes(n :: Number, set-constructor) -> Boolean: - nums = raw-build-array(n, lam(n2): random(2 * n2) end) - orig = make-arraynge(n) - nums-list = raw-array-to-list(nums) - expect = for raw-array-fold(lst from empty, elt from orig, _ from 0): - if not(nums-list.member(elt)): - link(elt, lst) - else: - lst - end - end.reverse() - result = for fold(s from set-constructor.make(orig), rem-elt from nums-list): - s.remove(rem-elt) - end.to-list().sort() - result == expect + nums = raw-build-array(n, lam(n2): random(2 * n2) end) + orig = make-arraynge(n) + nums-list = raw-array-to-list(nums) + expect = for raw-array-fold(lst from empty, elt from orig, _ from 0): + if not(nums-list.member(elt)): + link(elt, lst) + else: + lst + end + end.reverse() + result = for fold(s from set-constructor.make(orig), rem-elt from nums-list): + s.remove(rem-elt) + end.to-list().sort() + result == expect end check: - fun canonicalize(s): - s.to-list().sort() - end - c = canonicalize - fun test-constructor(s) block: + fun canonicalize(s): + s.to-list().sort() + end + c = canonicalize + fun test-constructor(s) block: # SKIP(wating for predicates/annotations) # Set(s([list: 1, 2])) is true # Set(s([list: ])) is true - [s: 1, 2, 3].member(2) is true - [s: 1, 2, 3].member(4) is false - [s: ].add(1) is [s: 1] - [s: 1].add(1) is [s: 1] - [s: 1, 2, 3].add(2) is [s: 1, 2, 3] - [s: 1, 2, 3].add(1.5) is [s: 1, 2, 3, 1.5] - [s: 1, 2].remove(18) is [s: 1, 2] - [s: 1, 2].remove(2) is [s: 1] - [s: 3, 1, 2].to-list().sort() is [list: 1, 2, 3] - [s: 1, 2].union([s: 2, 3]) is [s: 1, 2, 3] - [s: 1, 2].union([s: 4]) is [s: 1, 2, 4] - [s: 1, 2].intersect([s: 2, 3]) is [s: 2] - [s: 1, 2].intersect([s: 4]) is [s: ] - [s: 1, 2].difference([s: 2, 3]) is [s: 1] - [s: 1, 2].difference([s: 4]) is [s: 1, 2] - [s: 1, 2].symmetric-difference([s: 1, 2]) is [s: ] - c([s: 1, 2].symmetric-difference([s: 2, 3])) is c([s: 1, 3]) - c([s: 1, 2].symmetric-difference([s: 3, 4])) is c([s: 1, 2, 3, 4]) - ([s: 1, 2.1, 3] <> [s: 1, 2.2, 3]) is true - c([s: 1, 2, 4]) is c([s: 2, 1, 4]) - - for each(n from range(1,21)) block: - check-random-adds(n * 5, s) is true - check-random-removes(n * 5, s) is true - end - end + [s: 1, 2, 3].member(2) is true + [s: 1, 2, 3].member(4) is false + [s: ].add(1) is [s: 1] + [s: 1].add(1) is [s: 1] + [s: 1, 2, 3].add(2) is [s: 1, 2, 3] + [s: 1, 2, 3].add(1.5) is [s: 1, 2, 3, 1.5] + [s: 1, 2].remove(18) is [s: 1, 2] + [s: 1, 2].remove(2) is [s: 1] + [s: 3, 1, 2].to-list().sort() is [list: 1, 2, 3] + [s: 1, 2].union([s: 2, 3]) is [s: 1, 2, 3] + [s: 1, 2].union([s: 4]) is [s: 1, 2, 4] + [s: 1, 2].intersect([s: 2, 3]) is [s: 2] + [s: 1, 2].intersect([s: 4]) is [s: ] + [s: 1, 2].difference([s: 2, 3]) is [s: 1] + [s: 1, 2].difference([s: 4]) is [s: 1, 2] + [s: 1, 2].symmetric-difference([s: 1, 2]) is [s: ] + c([s: 1, 2].symmetric-difference([s: 2, 3])) is c([s: 1, 3]) + c([s: 1, 2].symmetric-difference([s: 3, 4])) is c([s: 1, 2, 3, 4]) + ([s: 1, 2.1, 3] <> [s: 1, 2.2, 3]) is true + c([s: 1, 2, 4]) is c([s: 2, 1, 4]) + + for each(n from range(1,21)) block: + check-random-adds(n * 5, s) is true + check-random-removes(n * 5, s) is true + end + end # test-constructor(set) - test-constructor(list-set) - test-constructor(tree-set) + test-constructor(list-set) + test-constructor(tree-set) end check "Different constructors should work well together": - fun canonicalize(s): - s.to-list().sort() - end - c = canonicalize - fun test-constructor(s-a, s-b) block: - [s-a: 1, 2].union([s-b: 2, 3]) is [s-a: 1, 2, 3] - [s-a: 1, 2].union([s-b: 4]) is [s-a: 1, 2, 4] - [s-a: 1, 2].intersect([s-b: 2, 3]) is [s-a: 2] - [s-a: 1, 2].intersect([s-b: 4]) is [s-a: ] - [s-a: 1, 2].difference([s-b: 2, 3]) is [s-a: 1] - [s-a: 1, 2].difference([s-b: 4]) is [s-a: 1, 2] - [s-a: 1, 2].symmetric-difference([s-b: 1, 2]) is [s-a: ] - c([s-a: 1, 2].symmetric-difference([s-b: 2, 3])) is c([s-a: 1, 3]) - c([s-a: 1, 2].symmetric-difference([s-b: 3, 4])) is c([s-a: 1, 2, 3, 4]) - ([s-a: 1, 2.1, 3] <> [s-b: 1, 2.2, 3]) is true - c([s-a: 1, 2, 4]) is c([s-b: 2, 1, 4]) - [s-a: 1, 2, 4].size() is 3 - [s-a: 1, 2, 4].size() is 3 - end - - test-constructor(list-set, tree-set) - test-constructor(tree-set, list-set) + fun canonicalize(s): + s.to-list().sort() + end + c = canonicalize + fun test-constructor(s-a, s-b) block: + [s-a: 1, 2].union([s-b: 2, 3]) is [s-a: 1, 2, 3] + [s-a: 1, 2].union([s-b: 4]) is [s-a: 1, 2, 4] + [s-a: 1, 2].intersect([s-b: 2, 3]) is [s-a: 2] + [s-a: 1, 2].intersect([s-b: 4]) is [s-a: ] + [s-a: 1, 2].difference([s-b: 2, 3]) is [s-a: 1] + [s-a: 1, 2].difference([s-b: 4]) is [s-a: 1, 2] + [s-a: 1, 2].symmetric-difference([s-b: 1, 2]) is [s-a: ] + c([s-a: 1, 2].symmetric-difference([s-b: 2, 3])) is c([s-a: 1, 3]) + c([s-a: 1, 2].symmetric-difference([s-b: 3, 4])) is c([s-a: 1, 2, 3, 4]) + ([s-a: 1, 2.1, 3] <> [s-b: 1, 2.2, 3]) is true + c([s-a: 1, 2, 4]) is c([s-b: 2, 1, 4]) + [s-a: 1, 2, 4].size() is 3 + [s-a: 1, 2, 4].size() is 3 + end + + test-constructor(list-set, tree-set) + test-constructor(tree-set, list-set) end check "pick on list sets doesn't repeat order": - s = [list-set: 1, 2, 3] - var found-diff = false - # This will fail every 2^100 times it is run, given that JS has a decent RNG - # and given the current sets implementation - for each(i from range(0, 100)): - when not(s.pick().elt == s.pick().elt): - found-diff := true - end - end - found-diff is true + s = [list-set: 1, 2, 3] + var found-diff = false + # This will fail every 2^100 times it is run, given that JS has a decent RNG + # and given the current sets implementation + for each(i from range(0, 100)): + when not(s.pick().elt == s.pick().elt): + found-diff := true + end + end + found-diff is true end check "sets pick visits all elements": - fun pick-sum(s): - cases(P.Pick) s.pick(): - | pick-none => 0 - | pick-some(elt, rest) => elt + pick-sum(rest) - end - end + fun pick-sum(s): + cases(P.Pick) s.pick(): + | pick-none => 0 + | pick-some(elt, rest) => elt + pick-sum(rest) + end + end - pick-sum([list-set: 1, 2, 3, 4]) is 10 - pick-sum([tree-set: 1, 2, 3, 4]) is 10 - pick-sum([list-set:]) is 0 - pick-sum([tree-set:]) is 0 + pick-sum([list-set: 1, 2, 3, 4]) is 10 + pick-sum([tree-set: 1, 2, 3, 4]) is 10 + pick-sum([list-set:]) is 0 + pick-sum([tree-set:]) is 0 end check "Set map-like function": - # Check empty sets: - sets.map-like(empty-list-set, lam(x): x + 1 end) is empty-list-set + # Check empty sets: + sets.map-like(empty-list-set, lam(x): x + 1 end) is empty-list-set - sets.map-like(empty-tree-set, lam(x): x + 1 end) is empty-tree-set + sets.map-like(empty-tree-set, lam(x): x + 1 end) is empty-tree-set - # Other tests: - sets.map-like([list-set: 1, 2, 3, 4], lam(x): 1 end) - is [list-set: 1] + # Other tests: + sets.map-like([list-set: 1, 2, 3, 4], lam(x): 1 end) + is [list-set: 1] - sets.map-like([tree-set: 1, 2, 3, 4], lam(x): 1 end) - is [tree-set: 1] + sets.map-like([tree-set: 1, 2, 3, 4], lam(x): 1 end) + is [tree-set: 1] - sets.map-like([list-set: 1, 2, 3, 4], lam(x): x + 1 end) - is [list-set: 5, 4, 3, 2] + sets.map-like([list-set: 1, 2, 3, 4], lam(x): x + 1 end) + is [list-set: 5, 4, 3, 2] - sets.map-like([tree-set: 1, 2, 3, 4], lam(x): x + 1 end) - is [tree-set: 5, 4, 3, 2] + sets.map-like([tree-set: 1, 2, 3, 4], lam(x): x + 1 end) + is [tree-set: 5, 4, 3, 2] - # Number -> String mapping test: - test-string = "abcd" + # Number -> String mapping test: + test-string = "abcd" - sets.map-like([list-set: 0, 1, 2, 3], - lam(x): - string-substring(test-string, x, x + 1) - end).to-list().sort() is [list: "a", "b", "c", "d"] + sets.map-like([list-set: 0, 1, 2, 3], + lam(x): + string-substring(test-string, x, x + 1) + end).to-list().sort() is [list: "a", "b", "c", "d"] - sets.map-like([tree-set: 0, 1, 2, 3], - lam(x): - string-substring(test-string, x, x + 1) - end).to-list().sort() is [list: "a", "b", "c", "d"] + sets.map-like([tree-set: 0, 1, 2, 3], + lam(x): + string-substring(test-string, x, x + 1) + end).to-list().sort() is [list: "a", "b", "c", "d"] - # String -> Number mapping test: - sets.map-like([list-set: "Arr", ",", "Hello", "Pyret", "mateys!"], string-length) - is [list-set: 1, 3, 7, 5] + # String -> Number mapping test: + sets.map-like([list-set: "Arr", ",", "Hello", "Pyret", "mateys!"], string-length) + is [list-set: 1, 3, 7, 5] - sets.map-like([tree-set: "Arr", ",", "Hello", "Pyret", "mateys!"],string-length) - is [tree-set: 1, 3, 7, 5] + sets.map-like([tree-set: "Arr", ",", "Hello", "Pyret", "mateys!"],string-length) + is [tree-set: 1, 3, 7, 5] end check "Set map-like method": - # Check empty sets: - empty-list-set.map-like(lam(x): x + 1 end) is empty-list-set + # Check empty sets: + empty-list-set.map-like(lam(x): x + 1 end) is empty-list-set - empty-tree-set.map-like(lam(x): x + 1 end) is empty-tree-set + empty-tree-set.map-like(lam(x): x + 1 end) is empty-tree-set - # Check map-like returns the same list type: - [list-set: 1, 2, 3, 4].map-like(lam(x): x end) - is [list-set: 1, 2, 3, 4] + # Check map-like returns the same list type: + [list-set: 1, 2, 3, 4].map-like(lam(x): x end) + is [list-set: 1, 2, 3, 4] - [tree-set: 1, 2, 3, 4].map-like(lam(x): x end) - is [tree-set: 1, 2, 3, 4] + [tree-set: 1, 2, 3, 4].map-like(lam(x): x end) + is [tree-set: 1, 2, 3, 4] - # Other tests: - [list-set: 1, 2, 3, 4].map-like(lam(x): 1 end) - is [list-set: 1] + # Other tests: + [list-set: 1, 2, 3, 4].map-like(lam(x): 1 end) + is [list-set: 1] - [list-set: 1, 2, 3, 4].map-like(lam(x): x + 1 end) - is [list-set: 5, 4, 3, 2] + [list-set: 1, 2, 3, 4].map-like(lam(x): x + 1 end) + is [list-set: 5, 4, 3, 2] - [tree-set: 1, 2, 3, 4].map-like(lam(x): x + 1 end) - is [tree-set: 5, 4, 3, 2] + [tree-set: 1, 2, 3, 4].map-like(lam(x): x + 1 end) + is [tree-set: 5, 4, 3, 2] - # Number -> String mapping test: - test-string = "abcd" + # Number -> String mapping test: + test-string = "abcd" - [list-set: 0, 1, 2, 3].map-like(lam(x): - string-substring(test-string, x, x + 1) - end).to-list().sort() is [list: "a", "b", "c", "d"] + [list-set: 0, 1, 2, 3].map-like(lam(x): + string-substring(test-string, x, x + 1) + end).to-list().sort() is [list: "a", "b", "c", "d"] - [tree-set: 0, 1, 2, 3].map-like(lam(x): - string-substring(test-string, x, x + 1) - end).to-list().sort() is [list: "a", "b", "c", "d"] + [tree-set: 0, 1, 2, 3].map-like(lam(x): + string-substring(test-string, x, x + 1) + end).to-list().sort() is [list: "a", "b", "c", "d"] - # String -> Number mapping test: - [list-set: "Arr", ",", "Hello", "Pyret", "mateys!"].map-like(string-length) - is [list-set: 1, 3, 7, 5] + # String -> Number mapping test: + [list-set: "Arr", ",", "Hello", "Pyret", "mateys!"].map-like(string-length) + is [list-set: 1, 3, 7, 5] - [tree-set: "Arr", ",", "Hello", "Pyret", "mateys!"].map-like(string-length) - is [tree-set: 1, 3, 7, 5] + [tree-set: "Arr", ",", "Hello", "Pyret", "mateys!"].map-like(string-length) + is [tree-set: 1, 3, 7, 5] end check "Set filter-like function": - sets.filter-like(lam(e): e > 5 end, [list-set: -1, 1]) is [list-set: ] - sets.filter-like(lam(e): e > 5 end, [tree-set: -1, 1]) is [tree-set: ] + sets.filter-like(lam(e): e > 5 end, [list-set: -1, 1]) is [list-set: ] + sets.filter-like(lam(e): e > 5 end, [tree-set: -1, 1]) is [tree-set: ] - sets.filter-like(lam(e): e > 0 end, [list-set: -1, 1]) is [list-set: 1] - sets.filter-like(lam(e): e > 0 end, [tree-set: -1, 1]) is [tree-set: 1] + sets.filter-like(lam(e): e > 0 end, [list-set: -1, 1]) is [list-set: 1] + sets.filter-like(lam(e): e > 0 end, [tree-set: -1, 1]) is [tree-set: 1] - sets.filter-like(lam(e): num-modulo(e, 2) == 0 end, - [list-set: 1, 2, 3, 4]) is [list-set: 2, 4] + sets.filter-like(lam(e): num-modulo(e, 2) == 0 end, + [list-set: 1, 2, 3, 4]) is [list-set: 2, 4] - sets.filter-like(lam(e): num-modulo(e, 2) == 0 end, - [tree-set: 1, 2, 3, 4]) is [tree-set: 2, 4] + sets.filter-like(lam(e): num-modulo(e, 2) == 0 end, + [tree-set: 1, 2, 3, 4]) is [tree-set: 2, 4] end check "Set filter-like method": - [list-set: -1, 1].filter-like(lam(e): e > 5 end) is [list-set: ] - [tree-set: -1, 1].filter-like(lam(e): e > 5 end) is [tree-set: ] + [list-set: -1, 1].filter-like(lam(e): e > 5 end) is [list-set: ] + [tree-set: -1, 1].filter-like(lam(e): e > 5 end) is [tree-set: ] - [list-set: -1, 1].filter-like(lam(e): e > 0 end) is [list-set: 1] - [tree-set: -1, 1].filter-like(lam(e): e > 0 end) is [tree-set: 1] + [list-set: -1, 1].filter-like(lam(e): e > 0 end) is [list-set: 1] + [tree-set: -1, 1].filter-like(lam(e): e > 0 end) is [tree-set: 1] - [list-set: 1, 2, 3, 4].filter-like(lam(e): num-modulo(e, 2) == 0 end) - is [list-set: 2, 4] + [list-set: 1, 2, 3, 4].filter-like(lam(e): num-modulo(e, 2) == 0 end) + is [list-set: 2, 4] - [tree-set: 1, 2, 3, 4].filter-like(lam(e): num-modulo(e, 2) == 0 end) - is [tree-set: 2, 4] + [tree-set: 1, 2, 3, 4].filter-like(lam(e): num-modulo(e, 2) == 0 end) + is [tree-set: 2, 4] end From cea9bfba7179927818d8ea4a59be060a6d10a60f Mon Sep 17 00:00:00 2001 From: Ethan Sattler Date: Sat, 4 Nov 2017 00:00:11 -0400 Subject: [PATCH 3/4] Updated `map` and `filter` to be more efficient. --- src/arr/trove/sets.arr | 43 +++++++++++++------ tests/pyret/tests/test-sets.arr | 76 ++++++++++++++++----------------- 2 files changed, 67 insertions(+), 52 deletions(-) diff --git a/src/arr/trove/sets.arr b/src/arr/trove/sets.arr index 6ea0866ef9..1d55bc65fa 100644 --- a/src/arr/trove/sets.arr +++ b/src/arr/trove/sets.arr @@ -13,8 +13,8 @@ provide { fold: set-fold, all: set-all, any: set-any, - map-like: set-map-like, - filter-like: set-filter-like + map: set-map, + filter: set-filter } end provide-types * @@ -371,12 +371,19 @@ data Set: self.elems.any(f) end, - method map-like(self, f) -> Set: - list-to-list-set(self.to-list().map(f)) + method map(self, f) -> Set: + self.fold(lam(acc, x): acc.add(f(x)) end, list-set(empty)) end, - method filter-like(self, f) -> Set: - list-to-list-set(self.to-list().filter(f)) + method filter(self, f) -> Set: + list-set(self.fold( + lam(acc, x): + if f(x): + link(x, acc) + else: + acc + end + end, empty)) end | tree-set(elems :: AVLTree) with: @@ -448,12 +455,20 @@ data Set: self.elems.any(f) end, - method map-like(self, f) -> Set: - list-to-tree-set(self.to-list().map(f)) + method map(self, f) -> Set: + list-to-tree-set(self.elems.fold-preorder( + lam(acc, ele): link(f(ele), acc) end, empty)) end, - method filter-like(self, f) -> Set: - list-to-tree-set(self.to-list().filter(f)) + method filter(self, f) -> Set: + list-to-tree-set(self.elems.fold-preorder( + lam(acc, ele): + if f(ele): + link(ele, acc) + else: + acc + end + end, empty)) end sharing: @@ -607,12 +622,12 @@ fun list-to-tree(lst :: lists.List): end end -fun set-map-like(s :: Set, f :: (T -> U)) -> Set: - s.map-like(f) +fun set-map(s :: Set, f :: (T -> U)) -> Set: + s.map(f) end -fun set-filter-like(f :: (T -> Boolean), s :: Set) -> Set: - s.filter-like(f) +fun set-filter(f :: (T -> Boolean), s :: Set) -> Set: + s.filter(f) end fun arr-to-list-set(arr :: RawArray) -> Set: diff --git a/tests/pyret/tests/test-sets.arr b/tests/pyret/tests/test-sets.arr index 69523dcfd9..1e9b957f09 100644 --- a/tests/pyret/tests/test-sets.arr +++ b/tests/pyret/tests/test-sets.arr @@ -170,120 +170,120 @@ check "sets pick visits all elements": end -check "Set map-like function": +check "Set map function": # Check empty sets: - sets.map-like(empty-list-set, lam(x): x + 1 end) is empty-list-set + sets.map(empty-list-set, lam(x): x + 1 end) is empty-list-set - sets.map-like(empty-tree-set, lam(x): x + 1 end) is empty-tree-set + sets.map(empty-tree-set, lam(x): x + 1 end) is empty-tree-set # Other tests: - sets.map-like([list-set: 1, 2, 3, 4], lam(x): 1 end) + sets.map([list-set: 1, 2, 3, 4], lam(x): 1 end) is [list-set: 1] - sets.map-like([tree-set: 1, 2, 3, 4], lam(x): 1 end) + sets.map([tree-set: 1, 2, 3, 4], lam(x): 1 end) is [tree-set: 1] - sets.map-like([list-set: 1, 2, 3, 4], lam(x): x + 1 end) + sets.map([list-set: 1, 2, 3, 4], lam(x): x + 1 end) is [list-set: 5, 4, 3, 2] - sets.map-like([tree-set: 1, 2, 3, 4], lam(x): x + 1 end) + sets.map([tree-set: 1, 2, 3, 4], lam(x): x + 1 end) is [tree-set: 5, 4, 3, 2] # Number -> String mapping test: test-string = "abcd" - sets.map-like([list-set: 0, 1, 2, 3], + sets.map([list-set: 0, 1, 2, 3], lam(x): string-substring(test-string, x, x + 1) end).to-list().sort() is [list: "a", "b", "c", "d"] - sets.map-like([tree-set: 0, 1, 2, 3], + sets.map([tree-set: 0, 1, 2, 3], lam(x): string-substring(test-string, x, x + 1) end).to-list().sort() is [list: "a", "b", "c", "d"] # String -> Number mapping test: - sets.map-like([list-set: "Arr", ",", "Hello", "Pyret", "mateys!"], string-length) + sets.map([list-set: "Arr", ",", "Hello", "Pyret", "mateys!"], string-length) is [list-set: 1, 3, 7, 5] - sets.map-like([tree-set: "Arr", ",", "Hello", "Pyret", "mateys!"],string-length) + sets.map([tree-set: "Arr", ",", "Hello", "Pyret", "mateys!"],string-length) is [tree-set: 1, 3, 7, 5] end -check "Set map-like method": +check "Set map method": # Check empty sets: - empty-list-set.map-like(lam(x): x + 1 end) is empty-list-set + empty-list-set.map(lam(x): x + 1 end) is empty-list-set - empty-tree-set.map-like(lam(x): x + 1 end) is empty-tree-set + empty-tree-set.map(lam(x): x + 1 end) is empty-tree-set - # Check map-like returns the same list type: - [list-set: 1, 2, 3, 4].map-like(lam(x): x end) + # Check map returns the same list type: + [list-set: 1, 2, 3, 4].map(lam(x): x end) is [list-set: 1, 2, 3, 4] - [tree-set: 1, 2, 3, 4].map-like(lam(x): x end) + [tree-set: 1, 2, 3, 4].map(lam(x): x end) is [tree-set: 1, 2, 3, 4] # Other tests: - [list-set: 1, 2, 3, 4].map-like(lam(x): 1 end) + [list-set: 1, 2, 3, 4].map(lam(x): 1 end) is [list-set: 1] - [list-set: 1, 2, 3, 4].map-like(lam(x): x + 1 end) + [list-set: 1, 2, 3, 4].map(lam(x): x + 1 end) is [list-set: 5, 4, 3, 2] - [tree-set: 1, 2, 3, 4].map-like(lam(x): x + 1 end) + [tree-set: 1, 2, 3, 4].map(lam(x): x + 1 end) is [tree-set: 5, 4, 3, 2] # Number -> String mapping test: test-string = "abcd" - [list-set: 0, 1, 2, 3].map-like(lam(x): + [list-set: 0, 1, 2, 3].map(lam(x): string-substring(test-string, x, x + 1) end).to-list().sort() is [list: "a", "b", "c", "d"] - [tree-set: 0, 1, 2, 3].map-like(lam(x): + [tree-set: 0, 1, 2, 3].map(lam(x): string-substring(test-string, x, x + 1) end).to-list().sort() is [list: "a", "b", "c", "d"] # String -> Number mapping test: - [list-set: "Arr", ",", "Hello", "Pyret", "mateys!"].map-like(string-length) + [list-set: "Arr", ",", "Hello", "Pyret", "mateys!"].map(string-length) is [list-set: 1, 3, 7, 5] - [tree-set: "Arr", ",", "Hello", "Pyret", "mateys!"].map-like(string-length) + [tree-set: "Arr", ",", "Hello", "Pyret", "mateys!"].map(string-length) is [tree-set: 1, 3, 7, 5] end -check "Set filter-like function": +check "Set filter function": - sets.filter-like(lam(e): e > 5 end, [list-set: -1, 1]) is [list-set: ] - sets.filter-like(lam(e): e > 5 end, [tree-set: -1, 1]) is [tree-set: ] + sets.filter(lam(e): e > 5 end, [list-set: -1, 1]) is [list-set: ] + sets.filter(lam(e): e > 5 end, [tree-set: -1, 1]) is [tree-set: ] - sets.filter-like(lam(e): e > 0 end, [list-set: -1, 1]) is [list-set: 1] - sets.filter-like(lam(e): e > 0 end, [tree-set: -1, 1]) is [tree-set: 1] + sets.filter(lam(e): e > 0 end, [list-set: -1, 1]) is [list-set: 1] + sets.filter(lam(e): e > 0 end, [tree-set: -1, 1]) is [tree-set: 1] - sets.filter-like(lam(e): num-modulo(e, 2) == 0 end, + sets.filter(lam(e): num-modulo(e, 2) == 0 end, [list-set: 1, 2, 3, 4]) is [list-set: 2, 4] - sets.filter-like(lam(e): num-modulo(e, 2) == 0 end, + sets.filter(lam(e): num-modulo(e, 2) == 0 end, [tree-set: 1, 2, 3, 4]) is [tree-set: 2, 4] end -check "Set filter-like method": +check "Set filter method": - [list-set: -1, 1].filter-like(lam(e): e > 5 end) is [list-set: ] - [tree-set: -1, 1].filter-like(lam(e): e > 5 end) is [tree-set: ] + [list-set: -1, 1].filter(lam(e): e > 5 end) is [list-set: ] + [tree-set: -1, 1].filter(lam(e): e > 5 end) is [tree-set: ] - [list-set: -1, 1].filter-like(lam(e): e > 0 end) is [list-set: 1] - [tree-set: -1, 1].filter-like(lam(e): e > 0 end) is [tree-set: 1] + [list-set: -1, 1].filter(lam(e): e > 0 end) is [list-set: 1] + [tree-set: -1, 1].filter(lam(e): e > 0 end) is [tree-set: 1] - [list-set: 1, 2, 3, 4].filter-like(lam(e): num-modulo(e, 2) == 0 end) + [list-set: 1, 2, 3, 4].filter(lam(e): num-modulo(e, 2) == 0 end) is [list-set: 2, 4] - [tree-set: 1, 2, 3, 4].filter-like(lam(e): num-modulo(e, 2) == 0 end) + [tree-set: 1, 2, 3, 4].filter(lam(e): num-modulo(e, 2) == 0 end) is [tree-set: 2, 4] end From 5a12211233bab266dbc6ae2f6ac64af218e0fae9 Mon Sep 17 00:00:00 2001 From: Ethan Sattler Date: Sat, 4 Nov 2017 00:41:41 -0400 Subject: [PATCH 4/4] Converted list-set's `filter` to use `list-set` and list's version of filter. --- src/arr/trove/sets.arr | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/arr/trove/sets.arr b/src/arr/trove/sets.arr index 1d55bc65fa..b637605407 100644 --- a/src/arr/trove/sets.arr +++ b/src/arr/trove/sets.arr @@ -376,14 +376,7 @@ data Set: end, method filter(self, f) -> Set: - list-set(self.fold( - lam(acc, x): - if f(x): - link(x, acc) - else: - acc - end - end, empty)) + list-set(self.to-list().filter(f)) end | tree-set(elems :: AVLTree) with: