% selector - Use boolean function to keep only matching elements from sequence
%
% selector :: (A->bool), seq(A) -> seq(A).
classdef selector < seq
	properties (GetAccess=private, SetAccess=private)
		fn       % :: A->bool
		source   % :: seq(A)
		x        % :: A
	end
	methods (Static)
		function o=make(fn,source)
			source=dropwhile(inverse(fn),source);
			if isempty(source), o=nil; else o=seq.selector(fn,source); end
		end
	end
	methods
		function d=selector(fn,source)
			d.fn=fn; 	
			d.x=head(source);
			d.source=source;
		end

		function z=elsize(o), z=elsize(d.x); end
		function s=tostring(o), s=sprintf('%s >> %s?',tostring(o.source),tostring(o.fn)); end
		function x=head(d), x=d.x; end
		function o=next(o)
			while 1
				o.source=next(o.source);
				if isempty(o.source), o=nil; return; end
				o.x=head(o.source);
				if o.fn(o.x), break; end
			end
		end
	end
end

function g=inverse(f), g=@(x)~f(x); end
