package org.enumerable.lambda.support.functionaljava;
import static fj.Ord.*;
import static fj.P.*;
import static fj.Show.*;
import static fj.data.Enumerator.*;
import static fj.data.Natural.*;
import static fj.data.Stream.*;
import static org.enumerable.lambda.support.functionaljava.LambdaFunctionalJava.*;
import static org.junit.Assert.*;
import java.math.BigInteger;
import org.enumerable.lambda.annotation.LambdaParameter;
import org.junit.Test;
import fj.Show;
import fj.data.Natural;
import fj.data.Stream;
/**
* Prints all primes less than n
*/
public class Primes2 {
@LambdaParameter
static Natural nn;
@LambdaParameter
static Stream<?> as;
// Finds primes in a given stream.
public static Stream<Natural> sieve(final Stream<Natural> xs) {
return cons(xs.head(),
p1(sieve(xs.tail()._1().removeAll(naturalOrd.equal().eq(ZERO).o(mod.f(xs.head()))))));
}
// A stream of all primes less than n.
public static Stream<Natural> primes(final Natural n) {
return sieve(forever(naturalEnumerator, natural(2).some())).takeWhile(naturalOrd.isLessThan(n));
}
@Test
public void test() {
final Natural n = natural(new BigInteger("42")).some();
final Show<Stream<Natural>> s = streamShow(naturalShow());
assertEquals("<2,3,5,7,11,13,17,19,23,29,31,37,41>", s.showS(primes(n)));
}
public static Show<Natural> naturalShow() {
return bigintShow().comap(λ(nn, nn.bigIntegerValue()));
}
@SuppressWarnings("unchecked")
public static <A> Show<Stream<A>> streamShow(final Show<A> sa) {
return show(λ((Stream<A>) as, join(((Stream<A>) as).map(sa.show_()).intersperse(fromString(",")).cons(fromString("<")).snoc(p(fromString(">"))))));
}
public static final Show<BigInteger> bigintShow() {
return Array_bind.anyShow();
}
}