Skip to content

X Maybe

John McClean edited this page Sep 11, 2018 · 2 revisions

Maybe : a safe, lazy Optional type

Maybe is an Optional type where chained operations are evaluated lazily. See also Option : a safe, eager Option type, which is an Eager Optional type. Maybe extends Option.

Creating Maybes

just : Just represents a value that is present

Maybe.just(10) //Just[10]

none : None represents the absence of a value

Maybe.nothing() //Nothing[]

maybe

Using Maybes

Maybe is used as return type in some terminal operations Cyclops ReactiveSeq which is a lazily evaluated Stream of data. This indicates that the operation is a lazy operation rather than an eager one. The terminal operation will not be triggered until an attempt is made to access the value inside the returned Maybe.

Maybe<Data> lazy = ReactiveSeq.generate(this::expensive)
                              .takeOne();

//the Stream is not activated yet

lazy.fold(data->process(data),()->emptyData()); //Stream activated

Stack safety

Maybe's functor and monad operations have built in trampolines for stack safe recursion, so this doesn't blow the stack!

@Test
public void fib() {
   System.out.println(fibonacci(just(tuple(100_000, 1l, 0l))));
}

public Maybe<Long> fibonacci(Maybe<Tuple3<Integer, Long, Long>> fib) {
    return fib.flatMap(t -> t.v1 == 0 ? just(t.v3) : 
                         fibonacci(just(tuple(t.v1 - 1, t.v2 + t.v3, t.v2))));
}

Reactive Maybes

Maybe can also be used reactively, that is data can be pushed asychronously into a Maybe instance while additional operations are chained sequentially to it (in a non-blocking manner).

CompletableMaybe<Integer> reactive = Maybe.maybe();

reactive.map(i->i+2); //non-blocking, no data present yet

//possibly on another thread
reactive.complete(10); //triggers the map operation to add 2
Clone this wiki locally