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

Eval.later memoizes or caches the result of it's evaluation while Eval.always always evaluates it.

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))));
}

orElse /coflatMap

orElse and coflatMap can be used to manage Maybe's that aren't present and provide a default value.

 

int result = Eval.now(null)
                  .orElse(-1); //-1

Eval.now(null)
     .coflatMap(eval->eval.visit(v->v,()->-1); //Eval[-1]

Applicative Functor

Combine values of any type asynchronously

Eval.later(()->10)
       .combine(Xor.primary(10),(a,b)->a+b);
//Eval.later[20] (lazy / caching op)

Accumulating

Accumulate allows us to accumulate the present values in a List of Maybes.

Eval<Integer> just = Eval.now(10);


Eval<Integer> maybes = Maybe.accumulate(Monoids.intSum,ListX.of(just,  Eval.just(1)));
//Eval.just(11)
Clone this wiki locally