Skip to content

Instantly share code, notes, and snippets.

@ab5tract
Created September 29, 2014 23:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ab5tract/b0421b4ecd03942d1ebc to your computer and use it in GitHub Desktop.
Save ab5tract/b0421b4ecd03942d1ebc to your computer and use it in GitHub Desktop.
diff --git a/src/core/set_operators.pm b/src/core/set_operators.pm
index 841851f..7f72e91 100644
--- a/src/core/set_operators.pm
+++ b/src/core/set_operators.pm
@@ -108,16 +108,35 @@ only sub infix:<<"\x2216">>(|p) {
infix:<(-)>(|p);
}
-proto sub infix:<(^)>($, $ --> Setty) {*}
-multi sub infix:<(^)>(Any $a, Any $b --> Setty) {
- $a.Set(:view) (^) $b.Set(:view);
-}
-multi sub infix:<(^)>(Set $a, Set $b --> Setty) {
- ($a (-) $b) (|) ($b (-) $a);
+only sub infix:<(^)>(**@p) {
+ return set() unless @p;
+
+ if @p.grep(Baggy) {
+ my $baghash = @p[0] ~~ BagHash
+ ?? BagHash.new-fp(@p.shift.keys)
+ !! @p.shift.BagHash;
+ for @p.map(*.Bag(:view)) -> $bag {
+ my $i = $baghash (|) $bag;
+ for $i.keys -> $k {
+ $baghash{$k} = $baghash{$k}
+ ?? abs $baghash{$k} - $bag{$k}
+ !! $bag{$k};
+ }
+ }
+ $baghash.Bag(:view);
+ } else {
+ my $sethash = @p[0] ~~ SetHash
+ ?? SetHash.new(@p.shift.keys)
+ !! @p.shift.SetHash;
+ for @p.map(*.Set(:view)) -> $set {
+ $sethash = ($sethash (-) $set) (|) ($set (-) $sethash);
+ }
+ $sethash.Set(:view);
+ }
}
# U+2296 CIRCLED MINUS
-only sub infix:<<"\x2296">>($a, $b --> Setty) {
- $a (^) $b;
+only sub infix:<<"\x2296">>(|p) {
+ infix:<(^)>(|p);
}
# TODO: polymorphic eqv
diff --git a/S03-operators/bag.t b/S03-operators/bag.t
index 69c5af7..bc62b46 100644
--- a/S03-operators/bag.t
+++ b/S03-operators/bag.t
@@ -1,7 +1,7 @@
use v6;
use Test;
-plan 128;
+plan 129;
sub showset($s) { $s.keys.sort.join(' ') }
@@ -66,8 +66,6 @@ sub symmetric-difference($a, $b) {
($a (|) $b) (-) ($b (&) $a)
}
-#?rakudo 8 todo "Rakudo update in progress, but not done yet"
-
is showkv($s (^) $b), showkv(symmetric-difference($s, $b)), "Bag symmetric difference with Set is correct";
isa_ok ($s (^) $b), Bag, "... and it's actually a Bag";
is showkv($b (^) $s), showkv(symmetric-difference($s, $b)), "Set symmetric difference with Bag is correct";
@@ -77,7 +75,7 @@ isa_ok ($b (^) $s), Bag, "... and it's actually a Bag";
is showkv($s (^) $kb), showkv(symmetric-difference($s, $kb)), "BagHash symmetric difference with Set is correct";
isa_ok ($s (^) $kb), Bag, "... and it's actually a Bag";
#?niecza todo "Test is wrong, implementation is wrong"
-is showkv($kb (^) $s), showkv(symmetric-difference($s, $kb)), "Set symmetric difference with BagHash is correct";
+is showkv($s (^) $kb), showkv(symmetric-difference($s, $kb)), "Set symmetric difference with BagHash is correct";
isa_ok ($kb (^) $s), Bag, "... and it's actually a Bag";
# Bag multiplication
@@ -194,20 +192,18 @@ ok bag(my @large_arr = ("a"...*)[^50000]), "... a large array goes into a bar -
is showkv([(.)] $s, $b), showkv({ blood => 2, love => 2 }), "Bag multiply reduce works on two sets";
is showkv([(.)] $s, $b, $kb), showkv({ blood => 2, love => 4 }), "Bag multiply reduce works on three sets";
- #?rakudo 5 skip "Crashing"
is showkv([(^)] @d), showset(‚àÖ), "Bag symmetric difference reduce works on nothing";
- is showkv([(^)] $s), showset($s), "Set symmetric difference reduce works on one set";
- isa_ok showkv([(^)] $s), Set, "Set symmetric difference reduce works on one set, yields set";
+ is showkv([(^)] $s), showkv($s.Set), "Set symmetric difference reduce works on one set";
+ isa_ok ([(^)] $s), Set, "Set symmetric difference reduce works on one set, yields set";
is showkv([(^)] $b), showkv($b), "Bag symmetric difference reduce works on one bag";
- isa_ok showkv([(^)] $b), Bag, "Bag symmetric difference reduce works on one bag, yields bag";
- #?rakudo 4 todo "Wrong answer at the moment"
+ isa_ok ([(^)] $b), Bag, "Bag symmetric difference reduce works on one bag, yields bag";
is showkv([(^)] $s, $b), showkv({ blood => 1, love => 1, rhetoric => 1 }), "Bag symmetric difference reduce works on a bag and a set";
- isa_ok showkv([(^)] $s, $b), Bag, "... and produces a Bag";
+ isa_ok ([(^)] $s, $b), Bag, "... and produces a Bag";
is showkv([(^)] $b, $s), showkv({ blood => 1, love => 1, rhetoric => 1 }), "... and is actually symmetric";
- isa_ok showkv([(^)] $b, $s), Bag, "... and still produces a Bag that way too";
- #?rakudo 2 skip "Crashing"
- is showkv([(^)] $s, $b, $kb), showkv({ blood => 1, love => 1, rhetoric => 1 }), "Bag symmetric difference reduce works on three bags";
- isa_ok showkv([(^)] $s, $b, $kb), Bag, "Bag symmetric difference reduce works on three bags";
+ isa_ok ([(^)] $b, $s), Bag, "... and still produces a Bag that way too";
+ is showkv([(^)] $s, $b, $kb), showkv({ love => 1, rhetoric => 1 }), "Bag symmetric difference reduce works on three bags";
+ isa_ok ([(^)] $s, $b, $kb), Bag, "... and produces a Bag when reducing three bags";
+ is showkv([(^)] $b, $kb, $s), showkv({ love => 1, rhetoric => 1 }), "Bag symmetric difference reduce works the same on three bags in a different order";
}
# vim: ft=perl6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment