@Test public void testLazyFlatMapMultiple() { List<Integer> eval = mlazy(asList(1, 2)) .flatMap(MonadicsTest.<Integer>twice()) .flatMap(MonadicsTest.<Integer>twice()) .eval(); assertArrayEquals(new Integer[]{1, 1, 1, 1, 2, 2, 2, 2}, eval.toArray(new Integer[]{})); }
public static <A> IteratorMonadic<A> mlazy(final Iterator<A> as) { return new IteratorMonadic<A>() { @Override public <B> IteratorMonadic<B> fmap(final Function<A, B> f) { return mlazy(new Iter<B>() { @Override public boolean hasNext() { return as.hasNext(); } @Override public B next() { return f.apply(as.next()); } }); } @Override public <B> IteratorMonadic<B> mapIndex(final Function2<A, Integer, B> f) { return mlazy(new Iter<B>() { private int i = 0; @Override public boolean hasNext() { return as.hasNext(); } @Override public B next() { return f.apply(as.next(), i++); } }); } @Override public <B> IteratorMonadic<B> bind(final Function<A, Iterator<B>> f) { return mlazy(new Iter<B>() { @Override public boolean hasNext() { return step.hasNext() || step().hasNext(); } @Override public B next() { if (step.hasNext()) { return step.next(); } else { return step().next(); } } private Iterator<B> step = Monadics.emptyIter(); private Iterator<B> step() { while (!step.hasNext() && as.hasNext()) { step = f.apply(as.next()); } return step; } }); } @Override public boolean exists(Function<A, Boolean> p) { for (A a : forc(as)) { if (p.apply(a)) return true; } return false; } @Override public IteratorMonadic<A> filter(final Function<A, Boolean> p) { return mlazy(new Iter<A>() { private A next = null; @Override public boolean hasNext() { if (next != null) { return true; } else { for (A a : forc(as)) { if (p.apply(a)) { next = a; return true; } } return false; } } @Override public A next() { try { if (next != null || hasNext()) { return next; } else { throw new NoSuchElementException(); } } finally { next = null; } } }); } @Override public IteratorMonadic<A> take(final int n) { return mlazy(new Iter<A>() { private int count = 0; @Override public boolean hasNext() { return count < n && as.hasNext(); } @Override public A next() { if (count < n) { count++; return as.next(); } else { throw new NoSuchElementException(); } } }); } @Override public IteratorMonadic<A> each(final Function<A, Void> e) { return mlazy(new Iter<A>() { @Override public boolean hasNext() { return as.hasNext(); } @Override public A next() { final A a = as.next(); e.apply(a); return a; } }); } @Override public IteratorMonadic<A> eachIndex(final Function2<A, Integer, Void> e) { return mlazy(new Iter<A>() { private int i = 0; @Override public boolean hasNext() { return as.hasNext(); } @Override public A next() { final A a = as.next(); e.apply(a, i++); return a; } }); } @Override public Iterator<A> iterator() { return as; } @Override public Iterator<A> value() { return as; } @Override public List<A> eval() { return toList(as); } }; }
Monadics { public static <A> IteratorMonadic<A> mlazy(final Iterator<A> as) { return new IteratorMonadic<A>() { @Override public <B> IteratorMonadic<B> fmap(final Function<A, B> f) { return mlazy(new Iter<B>() { @Override public boolean hasNext() { return as.hasNext(); } @Override public B next() { return f.apply(as.next()); } }); } @Override public <B> IteratorMonadic<B> mapIndex(final Function2<A, Integer, B> f) { return mlazy(new Iter<B>() { private int i = 0; @Override public boolean hasNext() { return as.hasNext(); } @Override public B next() { return f.apply(as.next(), i++); } }); } @Override public <B> IteratorMonadic<B> bind(final Function<A, Iterator<B>> f) { return mlazy(new Iter<B>() { @Override public boolean hasNext() { return step.hasNext() || step().hasNext(); } @Override public B next() { if (step.hasNext()) { return step.next(); } else { return step().next(); } } private Iterator<B> step = Monadics.emptyIter(); private Iterator<B> step() { while (!step.hasNext() && as.hasNext()) { step = f.apply(as.next()); } return step; } }); } @Override public boolean exists(Function<A, Boolean> p) { for (A a : forc(as)) { if (p.apply(a)) return true; } return false; } @Override public IteratorMonadic<A> filter(final Function<A, Boolean> p) { return mlazy(new Iter<A>() { private A next = null; @Override public boolean hasNext() { if (next != null) { return true; } else { for (A a : forc(as)) { if (p.apply(a)) { next = a; return true; } } return false; } } @Override public A next() { try { if (next != null || hasNext()) { return next; } else { throw new NoSuchElementException(); } } finally { next = null; } } }); } @Override public IteratorMonadic<A> take(final int n) { return mlazy(new Iter<A>() { private int count = 0; @Override public boolean hasNext() { return count < n && as.hasNext(); } @Override public A next() { if (count < n) { count++; return as.next(); } else { throw new NoSuchElementException(); } } }); } @Override public IteratorMonadic<A> each(final Function<A, Void> e) { return mlazy(new Iter<A>() { @Override public boolean hasNext() { return as.hasNext(); } @Override public A next() { final A a = as.next(); e.apply(a); return a; } }); } @Override public IteratorMonadic<A> eachIndex(final Function2<A, Integer, Void> e) { return mlazy(new Iter<A>() { private int i = 0; @Override public boolean hasNext() { return as.hasNext(); } @Override public A next() { final A a = as.next(); e.apply(a, i++); return a; } }); } @Override public Iterator<A> iterator() { return as; } @Override public Iterator<A> value() { return as; } @Override public List<A> eval() { return toList(as); } }; } }
Monadics { public static <A> IteratorMonadic<A> mlazy(final Iterator<A> as) { return new IteratorMonadic<A>() { @Override public <B> IteratorMonadic<B> fmap(final Function<A, B> f) { return mlazy(new Iter<B>() { @Override public boolean hasNext() { return as.hasNext(); } @Override public B next() { return f.apply(as.next()); } }); } @Override public <B> IteratorMonadic<B> mapIndex(final Function2<A, Integer, B> f) { return mlazy(new Iter<B>() { private int i = 0; @Override public boolean hasNext() { return as.hasNext(); } @Override public B next() { return f.apply(as.next(), i++); } }); } @Override public <B> IteratorMonadic<B> bind(final Function<A, Iterator<B>> f) { return mlazy(new Iter<B>() { @Override public boolean hasNext() { return step.hasNext() || step().hasNext(); } @Override public B next() { if (step.hasNext()) { return step.next(); } else { return step().next(); } } private Iterator<B> step = Monadics.emptyIter(); private Iterator<B> step() { while (!step.hasNext() && as.hasNext()) { step = f.apply(as.next()); } return step; } }); } @Override public boolean exists(Function<A, Boolean> p) { for (A a : forc(as)) { if (p.apply(a)) return true; } return false; } @Override public IteratorMonadic<A> filter(final Function<A, Boolean> p) { return mlazy(new Iter<A>() { private A next = null; @Override public boolean hasNext() { if (next != null) { return true; } else { for (A a : forc(as)) { if (p.apply(a)) { next = a; return true; } } return false; } } @Override public A next() { try { if (next != null || hasNext()) { return next; } else { throw new NoSuchElementException(); } } finally { next = null; } } }); } @Override public IteratorMonadic<A> take(final int n) { return mlazy(new Iter<A>() { private int count = 0; @Override public boolean hasNext() { return count < n && as.hasNext(); } @Override public A next() { if (count < n) { count++; return as.next(); } else { throw new NoSuchElementException(); } } }); } @Override public IteratorMonadic<A> each(final Function<A, Void> e) { return mlazy(new Iter<A>() { @Override public boolean hasNext() { return as.hasNext(); } @Override public A next() { final A a = as.next(); e.apply(a); return a; } }); } @Override public IteratorMonadic<A> eachIndex(final Function2<A, Integer, Void> e) { return mlazy(new Iter<A>() { private int i = 0; @Override public boolean hasNext() { return as.hasNext(); } @Override public A next() { final A a = as.next(); e.apply(a, i++); return a; } }); } @Override public Iterator<A> iterator() { return as; } @Override public Iterator<A> value() { return as; } @Override public List<A> eval() { return toList(as); } }; } private  Monadics(); }
Monadics { public static <A> IteratorMonadic<A> mlazy(final Iterator<A> as) { return new IteratorMonadic<A>() { @Override public <B> IteratorMonadic<B> fmap(final Function<A, B> f) { return mlazy(new Iter<B>() { @Override public boolean hasNext() { return as.hasNext(); } @Override public B next() { return f.apply(as.next()); } }); } @Override public <B> IteratorMonadic<B> mapIndex(final Function2<A, Integer, B> f) { return mlazy(new Iter<B>() { private int i = 0; @Override public boolean hasNext() { return as.hasNext(); } @Override public B next() { return f.apply(as.next(), i++); } }); } @Override public <B> IteratorMonadic<B> bind(final Function<A, Iterator<B>> f) { return mlazy(new Iter<B>() { @Override public boolean hasNext() { return step.hasNext() || step().hasNext(); } @Override public B next() { if (step.hasNext()) { return step.next(); } else { return step().next(); } } private Iterator<B> step = Monadics.emptyIter(); private Iterator<B> step() { while (!step.hasNext() && as.hasNext()) { step = f.apply(as.next()); } return step; } }); } @Override public boolean exists(Function<A, Boolean> p) { for (A a : forc(as)) { if (p.apply(a)) return true; } return false; } @Override public IteratorMonadic<A> filter(final Function<A, Boolean> p) { return mlazy(new Iter<A>() { private A next = null; @Override public boolean hasNext() { if (next != null) { return true; } else { for (A a : forc(as)) { if (p.apply(a)) { next = a; return true; } } return false; } } @Override public A next() { try { if (next != null || hasNext()) { return next; } else { throw new NoSuchElementException(); } } finally { next = null; } } }); } @Override public IteratorMonadic<A> take(final int n) { return mlazy(new Iter<A>() { private int count = 0; @Override public boolean hasNext() { return count < n && as.hasNext(); } @Override public A next() { if (count < n) { count++; return as.next(); } else { throw new NoSuchElementException(); } } }); } @Override public IteratorMonadic<A> each(final Function<A, Void> e) { return mlazy(new Iter<A>() { @Override public boolean hasNext() { return as.hasNext(); } @Override public A next() { final A a = as.next(); e.apply(a); return a; } }); } @Override public IteratorMonadic<A> eachIndex(final Function2<A, Integer, Void> e) { return mlazy(new Iter<A>() { private int i = 0; @Override public boolean hasNext() { return as.hasNext(); } @Override public A next() { final A a = as.next(); e.apply(a, i++); return a; } }); } @Override public Iterator<A> iterator() { return as; } @Override public Iterator<A> value() { return as; } @Override public List<A> eval() { return toList(as); } }; } private  Monadics(); static ListMonadic<A> mlist(final Collection<A> as); static ListMonadic<A> mlist(final List<A> as); static ListMonadic<A> mlist(final A... as); static ListMonadic<A> mlist(final Iterator<A> as); static IteratorMonadic<A> mlazy(final Iterator<A> as); static IteratorMonadic<A> mlazy(final List<A> as); }
Monadics { public static <A> IteratorMonadic<A> mlazy(final Iterator<A> as) { return new IteratorMonadic<A>() { @Override public <B> IteratorMonadic<B> fmap(final Function<A, B> f) { return mlazy(new Iter<B>() { @Override public boolean hasNext() { return as.hasNext(); } @Override public B next() { return f.apply(as.next()); } }); } @Override public <B> IteratorMonadic<B> mapIndex(final Function2<A, Integer, B> f) { return mlazy(new Iter<B>() { private int i = 0; @Override public boolean hasNext() { return as.hasNext(); } @Override public B next() { return f.apply(as.next(), i++); } }); } @Override public <B> IteratorMonadic<B> bind(final Function<A, Iterator<B>> f) { return mlazy(new Iter<B>() { @Override public boolean hasNext() { return step.hasNext() || step().hasNext(); } @Override public B next() { if (step.hasNext()) { return step.next(); } else { return step().next(); } } private Iterator<B> step = Monadics.emptyIter(); private Iterator<B> step() { while (!step.hasNext() && as.hasNext()) { step = f.apply(as.next()); } return step; } }); } @Override public boolean exists(Function<A, Boolean> p) { for (A a : forc(as)) { if (p.apply(a)) return true; } return false; } @Override public IteratorMonadic<A> filter(final Function<A, Boolean> p) { return mlazy(new Iter<A>() { private A next = null; @Override public boolean hasNext() { if (next != null) { return true; } else { for (A a : forc(as)) { if (p.apply(a)) { next = a; return true; } } return false; } } @Override public A next() { try { if (next != null || hasNext()) { return next; } else { throw new NoSuchElementException(); } } finally { next = null; } } }); } @Override public IteratorMonadic<A> take(final int n) { return mlazy(new Iter<A>() { private int count = 0; @Override public boolean hasNext() { return count < n && as.hasNext(); } @Override public A next() { if (count < n) { count++; return as.next(); } else { throw new NoSuchElementException(); } } }); } @Override public IteratorMonadic<A> each(final Function<A, Void> e) { return mlazy(new Iter<A>() { @Override public boolean hasNext() { return as.hasNext(); } @Override public A next() { final A a = as.next(); e.apply(a); return a; } }); } @Override public IteratorMonadic<A> eachIndex(final Function2<A, Integer, Void> e) { return mlazy(new Iter<A>() { private int i = 0; @Override public boolean hasNext() { return as.hasNext(); } @Override public A next() { final A a = as.next(); e.apply(a, i++); return a; } }); } @Override public Iterator<A> iterator() { return as; } @Override public Iterator<A> value() { return as; } @Override public List<A> eval() { return toList(as); } }; } private  Monadics(); static ListMonadic<A> mlist(final Collection<A> as); static ListMonadic<A> mlist(final List<A> as); static ListMonadic<A> mlist(final A... as); static ListMonadic<A> mlist(final Iterator<A> as); static IteratorMonadic<A> mlazy(final Iterator<A> as); static IteratorMonadic<A> mlazy(final List<A> as);  }