This is a work-in-progress java maven library to bring some of our beloved functional programming concepts to Java. Feel free to contribute. :)
Currently, the major features of Functjonal are:
- Simple Algebraic Structures: Functjonal provides interfaces for semigroups and monoids.
These structures operate on a specific domain. For example, a
Semigroup<A>
is a binary composition operator for values of typeA
. By convention, any type that is a semigroup or monoid should provide a respective implementation as apublic static final
field with the name of the structure in capslock. For example:Then, you can use the monoid as such:import de.variantsync.functjonal.category.Monoid; public record PassedHours(int hours, int minutes) { public static final Monoid<PassedHours> MONOID = Monoid.From( () -> new PassedHours(0, 0), (a, b) -> new PassedHours( a.hours() + b.hours() + ((a.minutes() + b.minutes()) / 60), (a.minutes() + b.minutes()) % 60 ) ); }
As java does not feature type classes and inheritance is insufficient (as for instance getting the neutral element from a monoid would require an instance of the monoid's data type), we decided to adopt this convention as it is also flexible to define multiple monoids over the same datatype (e.g.,List<PassedHours> hours = ...; // let's say you have a list of passed hours Monoid<PassedHours> m = PassedHours.MONOID; PassedHours result = hours.stream().reduce(m.neutral(), m::append);
(0, +)
and(1, *)
forint
). This convention also allows us to define monoids for higher-kinded types (which cannot be expressed in java). For example, Products are monoidal when their arguments are monoidal. - Results, also known as
Either
from Haskell. AResult<S, F>
is a sum type that either has a value of typeS
(indicating success) or a value of typeF
(indicating failure). - Product as a simple pair.
- Unit as an explicit representation for
void
. - Lazy evaluation. A
Lazy<A>
lazily encapsulates a value of typeA
that can be accessed withlazy.run()
. The first, timerun
is invoked, the value will be computed and cached. Subsequent calls ofrun
, directly return the cached value. In the background,Lazy<A>
is wraps aSupplier<A>
.
Other features include non-empty lists as well as further quality-of-life utilities for lists, maps, and iterators.