package org.seqcode.gsebricks.verbs;
import java.util.Iterator;
/* An Expander<A,B> maps an object of type A to a set of objects of type
B (represented as an Iterator<B>) */
public interface Expander<A,B> {
public Iterator<B> execute(A a);
public static class Compose<X,Y,Z> implements Expander<X,Z> {
private Expander<X,Y> first;
private Expander<Y,Z> second;
public Compose(Expander<X,Y> f1, Expander<Y,Z> f2) {
first = f1;
second = f2;
}
public Iterator<Z> execute(X a) {
return new LazyComposeIterator<X,Y,Z>(first.execute(a), second);
}
}
public static class LazyComposeIterator<X,Y,Z> implements Iterator<Z> {
private Iterator<Y> base;
private Iterator<Z> expanded;
private Expander<Y,Z> expander;
public LazyComposeIterator(Iterator<Y> itr, Expander<Y,Z> b) {
base = itr;
expander = b;
expanded = null;
findNext();
}
/* (non-Javadoc)
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
return expanded != null && expanded.hasNext();
}
private void findNext() {
while(base.hasNext() && (expanded == null || !expanded.hasNext())) {
expanded = expander.execute(base.next());
}
if(!base.hasNext()) {
expanded = null;
}
}
/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
public Z next() {
Z val = expanded.next();
findNext();
return val;
}
/* (non-Javadoc)
* @see java.util.Iterator#remove()
*/
public void remove() {
throw new UnsupportedOperationException();
}
}
}