/
Set.pm
123 lines (102 loc) · 4.12 KB
/
Set.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
class Set does Associative {
# We could use a hash here, but right now hash keys coerce to Str,
# so instead let's use an array and &uniq for the time being.
has @!elems;
multi method new(@elems) {
self.bless(self.CREATE, :elems( uniq @elems ));
}
multi method new(*@elems) {
self.bless(self.CREATE, :elems( uniq @elems ));
}
multi method new(%elems) {
self.bless(self.CREATE, :elems( %elems.keys ));
}
multi method new(Set $set) {
$set;
}
sub contains(@array, $value) {
for @array {
if $value === $_ {
return True;
}
}
return False;
}
method keys() { @!elems }
method values() { True xx +@!elems }
method elems() { +@!elems }
method exists($elem) { contains(@!elems, $elem) }
method Num() { +self.elems }
method Bool() { ?self.elems }
multi method union(@otherset) {
self.new((@!elems, @otherset));
}
multi method union(%otherset) {
self.union(%otherset.keys);
}
multi method intersection(@otherset) {
self.new(grep { contains(@otherset, $_) }, @!elems);
}
multi method intersection(%otherset) {
self.intersection(%otherset.keys);
}
multi method difference(%otherset) {
self.difference(%otherset.keys);
}
multi method difference(@otherset) {
self.new(grep { !contains(@otherset, $_) }, @!elems);
}
multi method subsetorequal(@otherset) {
?contains(@otherset, all(@!elems));
}
multi method subsetorequal(%otherset) {
self.subsetorequal(%otherset.keys);
}
multi method supersetorequal(@otherset) {
?contains(@!elems, all(@otherset));
}
multi method supersetorequal(%otherset) {
self.supersetorequal(%otherset.keys);
}
method equal($otherset) {
+self == +$otherset && self.subsetorequal($otherset);
}
method subset($otherset) {
+self < +Set.new($otherset) && self.subsetorequal($otherset);
}
method superset($otherset) {
+self > +Set.new($otherset) && self.supersetorequal($otherset);
}
method perl() {
'Set.new(' ~ join(', ', map { .perl }, @!elems) ~ ')';
}
}
our multi sub infix:<(|)>(Set $a, %b) { $a.union(%b) }
our multi sub infix:<(|)>( %a, %b) { Set.new( %a).union(%b) }
our multi sub infix:<(|)>( @a, %b) { Set.new(|@a).union(%b) }
our multi sub infix:<(|)>( @a, @b) { Set.new(|@a).union(@b) }
our multi sub infix:<(&)>(Set $a, %b) { $a.intersection(%b) }
our multi sub infix:<(&)>( %a, %b) { Set.new( %a).intersection(%b) }
our multi sub infix:<(&)>( @a, %b) { Set.new(|@a).intersection(%b) }
our multi sub infix:<(&)>( @a, @b) { Set.new(|@a).intersection(@b) }
our multi sub infix:<(-)>(Set $a, %b) { $a.difference(%b) }
our multi sub infix:<(-)>( %a, %b) { Set.new( %a).difference(%b) }
our multi sub infix:<(-)>( @a, %b) { Set.new(|@a).difference(%b) }
our multi sub infix:<(-)>( @a, @b) { Set.new(|@a).difference(@b) }
our multi sub infix:<(<=)>(Set $a, %b) { $a.subsetorequal(%b) }
our multi sub infix:<(<=)>( %a, %b) { Set.new( %a).subsetorequal(%b) }
our multi sub infix:<(<=)>( @a, %b) { Set.new(|@a).subsetorequal(%b) }
our multi sub infix:<(<=)>( @a, @b) { Set.new(|@a).subsetorequal(@b) }
our multi sub infix:«(>=)»(Set $a, %b) { $a.supersetorequal(%b) }
our multi sub infix:«(>=)»( %a, %b) { Set.new( %a).supersetorequal(%b) }
our multi sub infix:«(>=)»( @a, %b) { Set.new(|@a).supersetorequal(%b) }
our multi sub infix:«(>=)»( @a, @b) { Set.new(|@a).supersetorequal(@b) }
our multi sub infix:<(<)>(Set $a, %b) { $a.subset(%b) }
our multi sub infix:<(<)>( %a, %b) { Set.new( %a).subset(%b) }
our multi sub infix:<(<)>( @a, %b) { Set.new(|@a).subset(%b) }
our multi sub infix:<(<)>( @a, @b) { Set.new(|@a).subset(@b) }
our multi sub infix:«(>)»(Set $a, %b) { $a.superset(%b) }
our multi sub infix:«(>)»( %a, %b) { Set.new( %a).superset(%b) }
our multi sub infix:«(>)»( @a, %b) { Set.new(|@a).superset(%b) }
our multi sub infix:«(>)»( @a, @b) { Set.new(|@a).superset(@b) }
# vim: ft=perl6