Introduction
Vavr is a functional library designed especially for Java, it is very much like Scala. Vavr library has functional programming paradigms like Monads, Function Currying, Partial Functions, and the data-structures in Vavr are all Immutable. Vavr features can turn Java into a pure Functional Programming language. In this article, we will explore some of the Vavr features,
- Tuple
- Option Monad
- Try (Big Try)
- Function Currying
- Lazy
Let’s explore.
Tuple
The Tuple data structure doesn’t exist in Java. Tuple is a collection of heterogeneous elements means multiple data types can be combined, tuples are immutable in nature. Tuple in Vavr is not flexible as it’s in Python to store 2 different elements. ‘Tuple2’ should be used for 3 elements. Tuple3, there is an upper limit of 8 elements in Vavr.
Just like in Scala tuple elements can be accessed like ._1, ._2, and so on.
Tuple2<String, Integer> tuple = Tuple.of("David", 50);
System.out.println(tuple._1); //David
System.out.println(tuple._2); //50
Tuples can transform using the map function.
Tuple2<String, Integer> modifiedTuple = tuple.map(s -> s.toUpperCase(), a -> a);
System.out.println(modifiedTuple._1); //DAVID
Option Monad
Option Monad in Vavr is like Java 8’s Optional. Vavr’s Option is very much like Scala’s Option which represents the presence and absence of values using ‘Some’ and ‘None’.
Option<String> option = Option.of("David");
System.out.println(option.map(x -> x.toUpperCase())); // Some(David)
Option<String> option1 = Option.of(null);
System.out.println(option1.map(x -> x.toUpperCase())); //None
The Option class in Vavr has a collection of some extra methods than Java’s Optional, some of them are
- peek
- isLazy
- isDefined
Try
Try in Vavr is a type that represents a computation that can result in the exception or return computed value successfully. In short by using Try throws can be processed functionally, Try returns either ‘Success’ or ‘Failure’
Code flow using Try looks like,
Try.of(() -> functionCall())
.onSuccess(result -> result)
.onFailure(error -> error)
Failure Scenario
private static double calculate(Integer value) {
return value / 0;
}
public static void main(String[] args) {
Try.of(() - > calculate(20)).map(result - > result + 1).onSuccess(comp - > System.out.println("Comp:" + comp)).onFailure(error - > System.out.println("Error:" + error));
}
Output
Error:java.lang.ArithmeticException: / by zero
Success Scenario
private static double calculate(Integer value) {
return value / 1;
}
public static void main(String[] args) {
Try.of(() - > calculate(20)).map(result - > result + 1).onSuccess(comp - > System.out.println("Comp:" + comp)).onFailure(error - > System.out.println("Error:" + error));
}
Output
"Comp:" 21.0
Function Currying
Function Currying is a technique of applying a function partially by fixing the value of some of the parameters, Vavr supports functions up to 8 parameters.
Function2<String, String, String> email = (x, y) -> y + x;
Function1<String, String> email_pf = email.curried().apply("@gmail.com");
System.out.println(email_pf.curried().apply("David")); //[email protected]
The email function is adding two parameters, in the second function “@gmail.com” is fixed and we applied the currying on two functions where one has a fixed value and final value can vary.
Lazy
Lazy is also a monad, which represents a value that Lazily evaluated, meaning the computation is deferred until the result is absolutely required. The returned value is cached or memorized.
private static int getRandomValue() {
Random random = new Random();
return random.nextInt(100);
}
public static void main(String[] args) {
Lazy < Integer > lazy = Lazy.of(() - > getRandomValue());
System.out.println(lazy.isEvaluated()); //false
System.out.println(lazy.get()); //96
System.out.println(lazy.isEvaluated()); //true
System.out.println(lazy.get()); //96
}
The first ".isEvaluated()" returns false because the Lazy is not executed, In first ".get()" random is generated, Second "isEvaluated" is true because Lazy is executed, the last ".get()" return the Memoized Value.
Summary
Vavr is simple to use and features can be implemented with basic functional knowledge, but if you decide to use Vavr then I highly recommend going through functional programming concepts then Vavr will make more sense to you.