- https://www.vavr.io/vavr-docs/#_lifting
- https://static.javadoc.io/io.vavr/vavr/0.9.3/io/vavr/PartialFunction.html
- https://github.com/mtumilowicz/java11-vavr-function-lifting
- on the workshop we will try to fix failing
Workshop - answers:
Answers(same tests as inWorkshopbut correctly solved)
- a partial function from
XtoYis a functionf: K → Y, for someK c X. Forx e X\Kfunction is undefined - in programming, if partial function is called with a disallowed input value, it will typically throw an exception
- in particular - every function that throws an exception is a partial function
- partial function (to set intuition)
int do(int positive) { if (first < 0) { throw new IllegalArgumentException("Only positive integers are allowed"); } // other stuff } - vavr's partial function interface
public interface PartialFunction<T, R> { R apply(T t); boolean isDefinedAt(T value); // tests if a value is contained in the function's domain. }- the caller is responsible for calling the method
isDefinedAt()before this function is applied to the value - if the function is not defined for a specific value,
apply()may produce an arbitrary result- in particular - even random values
- more specifically it is not guaranteed that the function will throw an exception
- above example rewritten with vavr
class RandomIdentityAnswer implements PartialFunction<Integer, Integer> { @Override public Integer apply(Integer o) { if (!isDefinedAt(o)) { throw new IllegalArgumentException("Only positive integers are allowed"); } // other stuff } @Override public boolean isDefinedAt(Integer value) { return nonNull(value) && value > 0; } }
- the caller is responsible for calling the method
- It generalizes the concept of a function
f: X → Yby not forcingfto map every element ofXto an element ofY- That means a partial function works properly only for some input values
- If the function is called with a disallowed input value, it will typically throw an exception
- In programming - we usually lift partial function
f: (K c X) -> Ytog: X -> Option<Y>in such a manner:- A lifted function returns
Some, if the function is invoked with allowed input valuesg(x).get() = f(x)onK
- A lifted function returns
Noneinstead of throwing an exception, if the function is invoked with disallowedg(x) = Option.none()forx e X\K
- A lifted function returns
In vavr we have two approaches to lifting:
- lifting function with
OptionFunction2<Integer, Integer, Integer> divide = (a, b) -> a / b; Function2<Integer, Integer, Option<Integer>> lifted = Function2.lift(divide); - lifting function with
TryFunction2<Integer, Integer, Integer> divide = (a, b) -> a / b; Function2<Integer, Integer, Try<Integer>> lifted = Function2.liftTry(divide);