Supported Types

monads_everywhere.webp

Higher-Kinded-J provides Higher-Kinded Type (HKT) simulation capabilities, allowing various Java types and custom types to be used with generic functional type classes like Functor, Applicative, Monad, and MonadError.

This is achieved by representing the application of a type constructor F to a type A as Kind<F_WITNESS, A>, where F_WITNESS is a special "witness" or phantom type unique to the type constructor F.

supported_types.svg


Key for Understanding Entries:

  • Type: The Java type or custom type being simulated.
  • XxxKind<A> Interface: The specific Kind interface for this type (e.g., OptionalKind<A>). It extends Kind<XxxKind.Witness, A> and usually contains the nested final class Witness {}.
  • Witness Type F_WITNESS: The phantom type used as the first parameter to Kind (e.g., OptionalKind.Witness). This is what parameterizes the type classes (e.g., Monad<OptionalKind.Witness>).
  • XxxKindHelper Class: Provides widen and narrow methods.
    • For external types (like java.util.List, java.util.Optional), widen typically creates an internal XxxHolder record which implements XxxKind<A>, and narrow extracts the Java type from this holder.
    • For library-defined types (Id, IO, Maybe, Either, Validated, Try, monad transformers), the type itself directly implements XxxKind<A>. This means widen performs a null check and direct cast (zero overhead), and narrow checks instanceof the actual type and casts.
  • Type Class Instances: Concrete implementations of Functor<F_WITNESS>, Monad<F_WITNESS>, etc.

1. Id<A> (Identity)

  • Type Definition: A custom record (Id) that directly wraps a value A. It's the simplest monad.
  • IdKind<A> Interface: Id<A> itself implements IdKind<A>, and IdKind<A> extends Kind<IdKind.Witness, A>.
  • Witness Type F_WITNESS: IdKind.Witness
  • IdKindHelper: IdKindHelper (wrap casts Id to Kind, unwrap casts Kind to Id; narrow is a convenience for unwrap).
  • Type Class Instances:
  • Notes: Id.of(a) creates Id(a). map and flatMap operate directly. Useful as a base for monad transformers and generic programming with no extra effects. Id<A> directly implements IdKind<A>.
  • Usage: How to use the Identity Monad

2. java.util.List<A>

  • Type Definition: Standard Java java.util.List<A>.
  • ListKind<A> Interface: ListKind<A> extends Kind<ListKind.Witness, A>.
  • Witness Type F_WITNESS: ListKind.Witness
  • ListKindHelper: Uses an internal ListHolder<A> record that implements ListKind<A> to wrap java.util.List<A>.
  • Type Class Instances:
    • ListFunctor (Functor<ListKind.Witness>)
    • ListMonad (Monad<ListKind.Witness>)
  • Notes: Standard list monad behaviour. of(a) creates a singleton list List.of(a); of(null) results in an empty list.
  • Usage: How to use the List Monad

3. java.util.stream.Stream<A>

  • Type Definition: Standard Java java.util.stream.Stream<A>.
  • StreamKind<A> Interface: StreamKind<A> extends Kind<StreamKind.Witness, A>.
  • Witness Type F_WITNESS: StreamKind.Witness
  • StreamKindHelper: Uses an internal StreamHolder<A> record that implements StreamKind<A> to wrap java.util.stream.Stream<A>. Provides widen, narrow.
  • Type Class Instances:
    • StreamFunctor (Functor<StreamKind.Witness>)
    • StreamApplicative (Applicative<StreamKind.Witness>)
    • StreamMonad (MonadZero<StreamKind.Witness>)
    • StreamTraverse (Traverse<StreamKind.Witness>, Foldable<StreamKind.Witness>)
  • Notes: Lazy, potentially infinite sequences with single-use semantics - each Stream can only be consumed once. Attempting to reuse a consumed stream throws IllegalStateException. of(a) creates singleton stream; of(null) creates empty stream. zero() returns empty stream. Use StreamOps for additional utility operations.
  • Usage: How to use the Stream Monad

4. Trampoline<A>

  • Type Definition: Custom sealed interface (Trampoline) implementing stack-safe recursion through trampolining. Provides three constructors: Done<A> (completed computation), More<A> (deferred computation), and FlatMap<A, B> (monadic sequencing).
  • TrampolineKind<A> Interface: Trampoline<A> itself implements TrampolineKind<A>, and TrampolineKind<A> extends Kind<TrampolineKind.Witness, A>.
  • Witness Type F_WITNESS: TrampolineKind.Witness
  • TrampolineKindHelper: widen casts Trampoline to Kind; narrow casts Kind to Trampoline. Provides done(value) for completed computations and defer(supplier) for deferred evaluation.
  • Type Class Instances:
    • TrampolineFunctor (Functor<TrampolineKind.Witness>)
    • TrampolineMonad (Monad<TrampolineKind.Witness>)
  • Notes: Enables stack-safe tail recursion by converting recursive calls into iterative data structure processing, preventing StackOverflowError in deeply recursive computations (verified with 100,000+ iterations). done(value) creates an already evaluated result; defer(supplier) defers computation. The run() method executes the trampoline iteratively using an explicit stack. Essential for recursive algorithms (factorial, Fibonacci, tree traversals) and provides TrampolineUtils for guaranteed stack-safe applicative operations.
  • Usage: How to use the Trampoline Monad

5. Free<F, A>

  • Type Definition: Custom sealed interface (Free) representing programmes as data structures that can be interpreted in different ways. Provides three constructors: Pure<F,A> (terminal value), Suspend<F,A> (suspended computation), and FlatMapped<F,X,A> (monadic sequencing).
  • FreeKind<F, A> Interface: Free<F,A> itself implements FreeKind<F,A>, and FreeKind<F,A> extends Kind<FreeKind.Witness<F>, A>.
  • Witness Type F_WITNESS: FreeKind.Witness<F> (where F is the instruction set functor)
  • FreeKindHelper: widen casts Free to Kind; narrow casts Kind to Free. Provides pure(value), suspend(computation), liftF(fa, functor).
  • Type Class Instances:
    • FreeFunctor<F> (Functor<FreeKind.Witness<F>>)
    • FreeMonad<F> (Monad<FreeKind.Witness<F>>)
  • Notes: Enables building domain-specific languages (DSLs) as composable data structures. Programmes are interpreted via foldMap with natural transformations, allowing multiple interpreters (IO, Test, Optimisation, etc.). Stack-safe execution using Higher-Kinded-J's Trampoline monad internally, demonstrating library composability (verified with 10,000+ operations). Essential for separating programme description from execution, enabling testability and alternative interpretations. Provides liftF to lift functor values into Free, map and flatMap for composition, and foldMap for interpretation. Useful for building testable workflows, query languages, and effect systems where the same programme needs different execution strategies.
  • Usage: How to use the Free Monad

6. java.util.Optional<A>

  • Type Definition: Standard Java java.util.Optional<A>.
  • OptionalKind<A> Interface: OptionalKind<A> extends Kind<OptionalKind.Witness, A>.
  • Witness Type F_WITNESS: OptionalKind.Witness
  • OptionalKindHelper: Uses an internal OptionalHolder<A> record that implements OptionalKind<A> to wrap java.util.Optional<A>.
  • Type Class Instances:
    • OptionalFunctor (Functor<OptionalKind.Witness>)
    • OptionalMonad (MonadError<OptionalKind.Witness, Unit>)
  • Notes: Optional.empty() is the error state. raiseError(Unit.INSTANCE) creates Optional.empty(). of(value) uses Optional.ofNullable(value).
  • Usage: How to use the Optional Monad

7. Maybe<A>

  • Type Definition: Custom sealed interface (Maybe) with Just<A> (non-null) and Nothing<A> implementations.
  • MaybeKind<A> Interface: Just<T> and Nothing<T> directly implement MaybeKind<T>, which extends Kind<MaybeKind.Witness, T>.
  • Witness Type F_WITNESS: MaybeKind.Witness
  • MaybeKindHelper: widen performs null check and casts Maybe to Kind (zero overhead); narrow checks instanceof Maybe and casts. Provides just(value), nothing(), fromNullable(value).
  • Type Class Instances:
    • MaybeFunctor (Functor<MaybeKind.Witness>)
    • MaybeMonad (MonadError<MaybeKind.Witness, Unit>)
  • Notes: Nothing is the error state; raiseError(Unit.INSTANCE) creates Nothing. Maybe.just(value) requires non-null. MaybeMonad.of(value) uses Maybe.fromNullable().
  • Usage: How to use the Maybe Monad

8. Either<L, R>

  • Type Definition: Custom sealed interface (Either) with Left<L,R> and Right<L,R> records.
  • EitherKind<L, R> Interface: Either.Left<L,R> and Either.Right<L,R> directly implement EitherKind<L,R> (and EitherKind2<L,R> for bifunctor operations), which extends Kind<EitherKind.Witness<L>, R>.
  • Witness Type F_WITNESS: EitherKind.Witness<L> (Error type L is fixed for the witness).
  • EitherKindHelper: widen performs null check and casts Either to Kind (zero overhead); narrow checks instanceof Either and casts. Provides left(l), right(r).
  • Type Class Instances:
    • EitherFunctor<L> (Functor<EitherKind.Witness<L>>)
    • EitherMonad<L> (MonadError<EitherKind.Witness<L>, L>)
  • Notes: Right-biased. Left(l) is the error state. of(r) creates Right(r).
  • Usage: How to use the Either Monad

9. Try<A>

  • Type Definition: Custom sealed interface (Try) with Success<A> and Failure<A> (wrapping Throwable).
  • TryKind<A> Interface: Try<A> itself implements TryKind<A>, and TryKind<A> extends Kind<TryKind.Witness, A>.
  • Witness Type F_WITNESS: TryKind.Witness
  • TryKindHelper: wrap casts Try to Kind; unwrap casts Kind to Try. Provides success(value), failure(throwable), tryOf(supplier).
  • Type Class Instances:
    • TryFunctor (Functor<TryKind.Witness>)
    • TryApplicative (Applicative<TryKind.Witness>)
    • TryMonad (MonadError<TryKind.Witness, Throwable>)
  • Notes: Failure(t) is the error state. of(v) creates Success(v).
  • Usage: How to use the Try Monad

10. java.util.concurrent.CompletableFuture<A>

  • Type Definition: Standard Java java.util.concurrent.CompletableFuture<A>.
  • CompletableFutureKind<A> Interface: CompletableFutureKind<A> extends Kind<CompletableFutureKind.Witness, A>.
  • Witness Type F_WITNESS: CompletableFutureKind.Witness
  • CompletableFutureKindHelper: Uses an internal CompletableFutureHolder<A> record. Provides wrap, unwrap, join.
  • Type Class Instances:
    • CompletableFutureFunctor (Functor<CompletableFutureKind.Witness>)
    • CompletableFutureApplicative (Applicative<CompletableFutureKind.Witness>)
    • CompletableFutureMonad (Monad<CompletableFutureKind.Witness>)
    • CompletableFutureMonad (MonadError<CompletableFutureKind.Witness, Throwable>)
  • Notes: Represents asynchronous computations. A failed future is the error state. of(v) creates CompletableFuture.completedFuture(v).
  • Usage: How to use the CompletableFuture Monad

11. IO<A>

  • Type Definition: Custom interface (IO) representing a deferred, potentially side-effecting computation.
  • IOKind<A> Interface: IO<A> directly extends IOKind<A>, which extends Kind<IOKind.Witness, A>.
  • Witness Type F_WITNESS: IOKind.Witness
  • IOKindHelper: widen performs null check and returns the IO directly as Kind (zero overhead); narrow checks instanceof IO and casts. Provides delay(supplier), unsafeRunSync(kind).
  • Type Class Instances:
    • IOFunctor (Functor<IOKind.Witness>)
    • IOApplicative (Applicative<IOKind.Witness>)
    • IOMonad (Monad<IOKind.Witness>)
  • Notes: Evaluation is deferred until unsafeRunSync. Exceptions during execution are generally unhandled by IOMonad itself unless caught within the IO's definition.
  • Usage: How to use the IO Monad

12. Lazy<A>

  • Type Definition: Custom class (Lazy) for deferred computation with memoization.
  • LazyKind<A> Interface: Lazy<A> itself implements LazyKind<A>, and LazyKind<A> extends Kind<LazyKind.Witness, A>.
  • Witness Type F_WITNESS: LazyKind.Witness
  • LazyKindHelper: wrap casts Lazy to Kind; unwrap casts Kind to Lazy. Provides defer(supplier), now(value), force(kind).
  • Type Class Instances:
  • Notes: Result or exception is memoized. of(a) creates an already evaluated Lazy.now(a).
  • Usage: How to use the Lazy Monad

13. Reader<R_ENV, A>

  • Type Definition: Custom functional interface (Reader) wrapping Function<R_ENV, A>.
  • ReaderKind<R_ENV, A> Interface: Reader<R_ENV,A> itself implements ReaderKind<R_ENV,A>, and ReaderKind<R_ENV,A> extends Kind<ReaderKind.Witness<R_ENV>, A>.
  • Witness Type F_WITNESS: ReaderKind.Witness<R_ENV> (Environment type R_ENV is fixed).
  • ReaderKindHelper: wrap casts Reader to Kind; unwrap casts Kind to Reader. Provides reader(func), ask(), constant(value), runReader(kind, env).
  • Type Class Instances:
    • ReaderFunctor<R_ENV> (Functor<ReaderKind.Witness<R_ENV>>)
    • ReaderApplicative<R_ENV> (Applicative<ReaderKind.Witness<R_ENV>>)
    • ReaderMonad<R_ENV> (Monad<ReaderKind.Witness<R_ENV>>)
  • Notes: of(a) creates a Reader that ignores the environment and returns a.
  • Usage: How to use the Reader Monad

14. State<S, A>

  • Type Definition: Custom functional interface (State) wrapping Function<S, StateTuple<S, A>>.
  • StateKind<S,A> Interface: State<S,A> itself implements StateKind<S,A>, and StateKind<S,A> extends Kind<StateKind.Witness<S>, A>.
  • Witness Type F_WITNESS: StateKind.Witness<S> (State type S is fixed).
  • StateKindHelper: wrap casts State to Kind; unwrap casts Kind to State. Provides pure(value), get(), set(state), modify(func), inspect(func), runState(kind, initialState), etc.
  • Type Class Instances:
    • StateFunctor<S> (Functor<StateKind.Witness<S>>)
    • StateApplicative<S> (Applicative<StateKind.Witness<S>>)
    • StateMonad<S> (Monad<StateKind.Witness<S>>)
  • Notes: of(a) (pure) returns a without changing state.
  • Usage: How to use the State Monad

15. Writer<W, A>

  • Type Definition: Custom record (Writer) holding (W log, A value). Requires Monoid<W>.
  • WriterKind<W, A> Interface: Writer<W,A> itself implements WriterKind<W,A>, and WriterKind<W,A> extends Kind<WriterKind.Witness<W>, A>.
  • Witness Type F_WITNESS: WriterKind.Witness<W> (Log type W and its Monoid are fixed).
  • WriterKindHelper: wrap casts Writer to Kind; unwrap casts Kind to Writer. Provides value(monoid, val), tell(monoid, log), runWriter(kind), etc.
  • Type Class Instances: (Requires Monoid<W> for Applicative/Monad)
    • WriterFunctor<W> (Functor<WriterKind.Witness<W>>)
    • WriterApplicative<W> (Applicative<WriterKind.Witness<W>>)
    • WriterMonad<W> (Monad<WriterKind.Witness<W>>)
  • Notes: of(a) (value) produces a with an empty log (from Monoid.empty()).
  • Usage: How to use the Writer Monad

16. Validated<E, A>

  • Type Definition: Custom sealed interface (Validated) with Valid<E, A> (holding A) and Invalid<E, A> (holding E) implementations.
  • ValidatedKind<E, A> Interface: Defines the HKT structure (ValidatedKind) for Validated<E,A>. It extends Kind<ValidatedKind.Witness<E>, A>. Concrete Valid<E,A> and Invalid<E,A> instances are cast to this kind by ValidatedKindHelper.
  • Witness Type F_WITNESS: ValidatedKind.Witness<E> (Error type E is fixed for the HKT witness).
  • ValidatedKindHelper Class: (ValidatedKindHelper). widen casts Validated<E,A> (specifically Valid or Invalid instances) to Kind<ValidatedKind.Witness<E>, A>. narrow casts Kind back to Validated<E,A>. Provides static factory methods valid(value) and invalid(error) that return the Kind-wrapped type.
  • Type Class Instances: (Error type E is fixed for the monad instance)
    • ValidatedMonad<E> (MonadError<ValidatedKind.Witness<E>, E>). This also provides Monad, Functor, and Applicative behaviour.
  • Notes: Validated is right-biased, meaning operations like map and flatMap apply to the Valid case and propagate Invalid untouched. ValidatedMonad.of(a) creates a Valid(a). As a MonadError, ValidatedMonad provides raiseError(error) to create an Invalid(error) and handleErrorWith(kind, handler) for standardised error recovery. The ap method is also right-biased and does not accumulate errors from multiple Invalids in the typical applicative sense; it propagates the first Invalid encountered or an Invalid function.
  • Usage: How to use the Validated Monad

17. Const<C, A>

  • Type Definition: Custom record (Const) holding a constant value of type C whilst treating A as a phantom type parameter (present in the type signature but not stored).
  • ConstKind2<C, A> Interface: (ConstKind2<C, A>) extends Kind2<ConstKind2.Witness, C, A>. This interface allows Const to be used with bifunctor operations.
  • Witness Type F_WITNESS: ConstKind2.Witness (used for bifunctor type class instances).
  • ConstKindHelper Class: (ConstKindHelper). Provides widen2 to cast Const<C, A> to Kind2<ConstKind2.Witness, C, A> and narrow2 to cast back. Uses an internal ConstKind2Holder<C, A> record that implements ConstKind2<C, A>.
  • Type Class Instances: (Only bifunctor, no monad instance as mapping the phantom type has no computational effect)
    • ConstBifunctor (Bifunctor<ConstKind2.Witness>). This instance provides first (transforms the constant value), second (changes only the phantom type), and bimap (combines both, though only first affects the constant value).
  • Notes: The second type parameter A is phantom—it exists only in the type signature and has no runtime representation. Calling mapSecond or second preserves the constant value whilst changing the phantom type in the signature. This makes Const particularly useful for fold implementations (accumulating a single value), getter patterns in lens libraries (van Laarhoven lenses), and data extraction from structures without transformation. The mapper function in second is applied to null for exception propagation, so use null-safe mappers. Similar to Const in Scala's Cats and Scalaz libraries.
  • Usage: How to use the Const Type