Skip to content
johnmcclean-aol edited this page Nov 23, 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).

Class hierarchy

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

Eval extends the following cyclops types (and others) ApplicativeFunctor, Filterable, Foldable, Functor, MonadicValue1, To, Value,Visitable and Zippable

Example

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