Skip to content
johnmcclean-aol edited this page Nov 21, 2016 · 6 revisions

The Eval type in is a monadic container for Lazy values. It is a Supplier on steroids, and it’s implementation was heavily influenced by Eval from the Scala library Cats (see http://eed3si9n.com/herding-cats/Eval.html).

Eval

  1. Now : An eagerly evaluated value
  2. Later : A value that will be evaluated exactly once in the future if triggered
  3. Always : A value that will be evaluated every time it is accessed in the future
public void expensive(){
       Eval<Integer> myExpensiveValue= cache? Eval.later(()->expensiveValue()); 
	                                    : Eval.always(()->expensiveValue());
       
	processStuff(myExpensiveValue).forEach(System.out::println);
	processStuff(myExpensiveValue).forEach(System.out::println);
	
}
public Eval<String> processStuff(Eval<Integer> myExpensiveValue){
	return myExpensiveValue.map(i->"converted " +i);
}

Stack safe recursion

The map / flatMap operators in Eval (and related operators such as patternMatch and peek) convert recursive tail calls to iteration.

public void fib3(){
    System.out.println(fibonacci(Eval.now(tuple(100_000,1l,0l))));
}
    
public Eval<Long> fibonacci(Eval<Tuple3<Integer,Long,Long>> fib)  {
    return fib.flatMap(t->t.v1 ==  0 ? Eval.now(t.v3) : fibonacci(Eval.now(tuple(t.v1-1,t.v2+t.v3,t.v2))));
}
Clone this wiki locally