Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement Supply.uniq
  • Loading branch information
lizmat committed Apr 18, 2014
1 parent 3922904 commit 9ce36b9
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 7 deletions.
15 changes: 8 additions & 7 deletions src/core/Supply.pm
Expand Up @@ -81,13 +81,14 @@ my role Supply {
}, *;
}

method for(|c) { SupplyOperations.for(|c) }
method interval(|c) { SupplyOperations.interval(|c) }
method do(&side_effect) { SupplyOperations.do(self, &side_effect) }
method grep(&filter) { SupplyOperations.grep(self, &filter) }
method map(&mapper) { SupplyOperations.map(self, &mapper) }
method merge($s) { SupplyOperations.merge(self, $s) }
method zip($s, *@with) { SupplyOperations.zip(self, $s, |@with) }
method for(|c) { SupplyOperations.for(|c) }
method interval(|c) { SupplyOperations.interval(|c) }
method do(&side_effect) { SupplyOperations.do(self, &side_effect) }
method grep(&filter) { SupplyOperations.grep(self, &filter) }
method map(&mapper) { SupplyOperations.map(self, &mapper) }
method uniq(:&as,:&with) { SupplyOperations.uniq(self, :&as, :&with) }
method merge($s) { SupplyOperations.merge(self, $s) }
method zip($s, *@with) { SupplyOperations.zip(self, $s, |@with) }
}

# The on meta-combinator provides a mechanism for implementing thread-safe
Expand Down
59 changes: 59 additions & 0 deletions src/core/SupplyOperations.pm
Expand Up @@ -101,6 +101,65 @@ my class SupplyOperations is repr('Uninstantiable') {
}
GrepSupply.new(:source($a), :&filter)
}

method uniq(Supply $a, :&as, :&with) {
my class UniqSupply does Supply does PrivatePublishing {
has $!source;
has &!as;
has &!with;

submethod BUILD(:$!source, :&!as, :&!with) { }

method tap(|c) {
my $sub = self.Supply::tap(|c);
my &more = do {
if &!with and &!with !=== &[===] {
my @seen; # should be Mu, but doesn't work in settings
my Mu $target;
&as
?? -> \val {
$target = &!as(val);
if @seen.first({ &!with($target,$_) } ) =:= Nil {
@seen.push($target);
self!more(val);
}
}
!! -> \val {
if @seen.first({ &!with(val,$_) } ) =:= Nil {
@seen.push(val);
self!more(val);
}
};
}
else {
my $seen := nqp::hash();
my str $target;
&as
?? -> \val {
$target = nqp::unbox_s(&!as(val).WHICH);
unless nqp::existskey($seen, $target) {
nqp::bindkey($seen, $target, 1);
self!more(val);
}
}
!! -> \val {
$target = nqp::unbox_s(val.WHICH);
unless nqp::existskey($seen, $target) {
nqp::bindkey($seen, $target, 1);
self!more(val);
}
};
}
};
$!source.tap( &more,
done => { self!done(); },
quit => -> $ex { self!quit($ex) }
);
$sub
}
}
UniqSupply.new(:source($a), :&as, :&with);
}

method map(Supply $a, &mapper) {
my class MapSupply does Supply does PrivatePublishing {
Expand Down

0 comments on commit 9ce36b9

Please sign in to comment.