Learning by Example
"For the things we have to learn before we can do them, we learn by doing them."
— Aristotle, Nicomachean Ethics
The best way to understand functional programming in Java is to see it in action. This chapter presents a curated collection of runnable examples that demonstrate how to apply Higher-Kinded-J patterns to real problems.
Each example is complete and self-contained. You can run them, modify them, and use them as starting points for your own code. The examples progress from simple demonstrations of individual concepts to complete applications that show how the pieces fit together.
- Basic Examples – Core type demonstrations, from Maybe and Either to Monad Transformers
- Effect Path API – Fluent composition of computations with error handling, validation, and resource management
- Optics – Type-safe navigation and transformation of nested immutable data structures
- Complete Applications – Production-quality examples showing how functional patterns solve real problems
Running Examples
All examples can be run using Gradle:
./gradlew :hkj-examples:run -PmainClass=<fully.qualified.ClassName>
For example:
./gradlew :hkj-examples:run -PmainClass=org.higherkindedj.example.basic.maybe.MaybeExample
Example Categories
Core Types
The foundation of functional programming: monadic types that represent different computational effects.
| Category | Examples | What You'll Learn |
|---|---|---|
| Optional Values | MaybeExample, OptionalExample | Safe handling of missing values |
| Error Handling | EitherExample, TryExample | Typed errors and exception handling |
| Validation | ValidatedMonadExample | Accumulating multiple errors |
| Side Effects | IOExample, LazyExample | Deferred and controlled execution |
| State & Environment | StateExample, ReaderExample, WriterExample | Pure state threading and dependency injection |
| Concurrency | CompletableFutureExample, VTaskPathExample | Async operations and virtual threads |
Monad Transformers
Combining multiple effects into unified stacks.
| Transformer | Example | What You'll Learn |
|---|---|---|
| EitherT | EitherTExample | Async operations with typed errors |
| MaybeT | MaybeTExample | Optional values in effectful contexts |
| ReaderT | ReaderTExample | Dependency injection with effects |
| StateT | StateTExample | Stateful computation within effects |
Effect Path API
Fluent, railway-oriented programming with composable effects.
| Category | Examples | What You'll Learn |
|---|---|---|
| Path Basics | BasicPathExample, ChainedComputationsExample | Creating paths, map/via, chaining |
| Error Handling | ErrorHandlingExample, ServiceLayerExample | recover, mapError, handleError |
| Validation | ValidationPipelineExample, AccumulatingValidationExample | Combining validations, error accumulation |
| ForPath | ForPathExample | Comprehension syntax for paths |
| Concurrency | ParallelExecutionExample, ScopeExample | Parallel execution, structured concurrency |
| Resilience | ResilienceExample, ResourceManagementExample | Retry policies, resource safety |
Optics
Type-safe lenses, prisms, and traversals for immutable data.
| Category | Examples | What You'll Learn |
|---|---|---|
| Core Optics | LensUsageExample, PairedLensExample, PrismUsageExample, IsoUsageExample, AffineUsageExample | Fundamental optic types |
| Traversals | TraversalUsageExample, FilteredTraversalExample | Multiple focus points, filtering |
| Focus DSL | NavigatorExample, KindFieldFocusExample, TraverseIntegrationExample, ValidationPipelineExample, AsyncFetchExample | Fluent navigation, validation, and async patterns |
| Fluent API | FluentApiExample, FreeDslExample | Fluent optic operations, Free monad DSL |
| External Types | ImportOpticsBasicExample, SpecInterfaceUsageExample | Optics for types you don't own |
| Cookbook | DeepUpdateRecipes, CollectionRecipes | Ready-to-use patterns |
Context and Concurrency
Thread-safe context propagation with Java's ScopedValue API.
| Example | What You'll Learn |
|---|---|
| ContextBasicExample | Basic Context with ask, asks, map, flatMap |
| ContextScopeExample | Context with Scope for structured concurrency |
| RequestContextExample | Request context propagation across layers |
| SecurityContextExample | Authentication and authorization patterns |
| DistributedTracingExample | Tracing across microservice boundaries |
Featured Applications
These complete applications demonstrate how functional patterns come together to solve real problems.
Order Processing Workflow
A production-quality e-commerce workflow demonstrating:
- Typed error hierarchies with sealed interfaces
- ForPath comprehensions for readable workflow composition
- Resilience patterns: retries, timeouts, circuit breakers
- Structured concurrency with VTask and Scope
- Focus DSL for immutable state updates
Draughts (Checkers) Game
An interactive command-line game demonstrating:
- Pure state management with
WithStatePath - Railway-oriented validation using
EitherPath - Side effect encapsulation with
IOPath - Focus DSL for navigating game state
- Stream-based patterns for declarative iteration
Complete Examples Reference
For a comprehensive listing of all examples with run commands, see the Examples Guide in the repository.
Chapter Contents
- Order Processing Workflow – Building production-ready business workflows
- Draughts Game – Pure functional game development