Interactive Tutorials: Learn Higher-Kinded-J by Building

The best way to understand Higher-Kinded Types and Optics is not to read about them but to write them — to run a test, watch it fail, change one line, and watch it pass. This chapter is built around that loop.

What Makes These Tutorials Different?

Rather than passive reading, we will:

  • Write real code by replacing answerRequired() placeholders with working implementations
  • Get immediate feedback because each test fails until our solution is correct
  • Build progressively — earlier concepts become tools for later challenges
  • See practical applications — every exercise solves a problem Java developers face routinely

Think of the chapter as a guided laboratory for functional programming patterns in Java.

Thirteen Focused Journeys

Each journey is designed for a single sitting (20-65 minutes). Short enough to stay focused; long enough to build real understanding.

Start Here for Practical Use

After completing Core: Foundations the Effect API journey is the recommended next step. It teaches the primary user-facing API of Higher-Kinded-J.

JourneyDurationExercisesFocus
Effect API~65 min15Effect paths, ForPath, Contexts

Expression Journey

JourneyDurationExercisesFocus
Expression: ForState~25 min11Named fields, guards, pattern matching, zoom

Concurrency Journeys

JourneyDurationExercisesFocus
Concurrency: VTask~45 min16Virtual threads, VTask, VTaskPath, Par combinators
Concurrency: Scope & Resource~30 min12Structured concurrency, resource management

Resilience Journey

JourneyDurationExercisesFocus
Resilience Patterns~45 min22Circuit breaker, saga, retry, bulkhead

Core Types Journeys (Foundation)

JourneyDurationExercisesFocus
Foundations~40 min24Kind, Functor, Applicative, Monad
Error Handling~30 min20MonadError, Either, Maybe, Validated
Advanced Patterns~40 min26Natural Transformations, Coyoneda, Free Ap, Static Analysis

Optics Journeys

JourneyDurationExercisesFocus
Lens & Prism~40 min30Lens, Prism, Affine fundamentals
Traversals & Practice~40 min27Traversals, composition, real-world use
Fluent & Free DSL~35 min22Fluent API, Free Monad DSL
Focus DSL~35 min29Type-safe path navigation, container widening

How the Tutorials Work

The Exercise Pattern

Each tutorial contains multiple exercises following this pattern:

@Test
void exercise1_yourFirstChallenge() {
    // 1. Context: what we are working with
    Either<String, Integer> value = Either.right(42);

    // 2. Task: what we need to implement
    // TODO: Transform the value by doubling it
    Either<String, Integer> result = answerRequired();

    // 3. Verification: the test checks our solution
    assertThat(result.getRight()).isEqualTo(84);
}

We replace answerRequired() with working code. The test fails with a clear error message until we get it right.

Tiered Hints

Newer exercise files use a three-tier hint structure so we can read just enough to get unstuck without seeing the answer:

// Nudge:    What concept applies here?
// Strategy: Which method on Either turns A into B?
// Spoiler:  value.map(n -> n * 2)

Read top-to-bottom and stop as soon as we have what we need.

The Learning Loop

  1. Read the exercise description and the Nudge
  2. Write our solution in place of answerRequired()
  3. Run the test (Ctrl+Shift+F10 in IntelliJ, Cmd+Shift+T in Eclipse)
  4. Observe the result:
    • ✅ Green: correct — move on
    • ❌ Red: read the error message and the Strategy hint
  5. Iterate until we understand the pattern, not just until the test passes

Tracking Our Progress

./gradlew :hkj-examples:tutorialProgress

This task scans the tutorial test files, counts the remaining answerRequired() calls per journey, and prints a per-journey progress bar. Useful for finding our place after a break.

Getting Unstuck

If we are struggling with an exercise:

  1. Read the Javadoc carefully — comments contain hints and links to relevant documentation
  2. Check the type signatures — what type does the method expect? what does it return?
  3. Look at earlier exercises — we may already have used a similar pattern
  4. Consult the documentation — links are provided throughout the tutorials
  5. Peek at the solution — solutions live in solutions/<journey>/ directories. Each @Test method in a solution carries a Javadoc block in the Why this is idiomatic / Alternative / Common wrong attempt format; reading that prose first is usually more useful than reading the working code on its own. See the Solutions Guide for the format and how to use it.

Resist the temptation to copy-paste. We will learn far more from struggling for five minutes than from reading the answer immediately. The struggle is where the learning happens.

Prerequisites

Required Knowledge

  • Java fundamentals: records, generics, lambdas, method references
  • IDE proficiency: running tests, navigating code, using auto-completion
  • Basic functional concepts: helpful but not required; we introduce them as needed

Technical Setup

  • Java 25 or later: the library uses modern Java features
  • Build tool: Gradle or Maven with the Higher-Kinded-J dependencies configured
  • IDE: IntelliJ IDEA, Eclipse, or VS Code with Java extensions

Verify Our Setup

The fastest way is the Tutorial00_OneLineSixLayers exercise, which doubles as the chapter's anchor:

./gradlew :hkj-examples:tutorialTest --tests "*Tutorial00_OneLineSixLayers*"

If we see a test failure with "Answer required", everything is wired up correctly and we are ready to go.

Running Tutorials

Tutorial exercises are run using a dedicated Gradle task:

# Run all tutorial exercises
./gradlew :hkj-examples:tutorialTest

# Run a specific tutorial
./gradlew :hkj-examples:tutorialTest --tests "*Tutorial01_KindBasics*"

# Run VTask concurrency tutorials
./gradlew :hkj-examples:tutorialTest --tests "*TutorialVTask*"

# See progress across journeys
./gradlew :hkj-examples:tutorialProgress

Test Configuration

Tutorial tests are excluded from ./gradlew test because they are incomplete by design. The solution tests are included and must pass to ensure each tutorial is correctly designed.

CommandDescription
./gradlew testRuns solution tests only (must pass)
./gradlew :hkj-examples:tutorialTestRuns tutorial exercises (expected to fail until we complete them)
./gradlew :hkj-examples:tutorialProgressPrints how many answerRequired() calls remain per journey

See the full Learning Paths guide for detailed sequences. A quick overview:

Quickstart (2 sessions)

Core: FoundationsEffect API

Practical FP (4 sessions)

Core: FoundationsError HandlingEffect APIOptics: Lens & Prism

Optics Specialist (4 sessions)

Lens & PrismTraversalsFluent & FreeFocus DSL

Full Curriculum (13 sessions)

All journeys in recommended order. See Learning Paths.

What We Will Build

By the end of these tutorials, we will have hands-on experience building:

From Core Types Journeys

  • A form validation system using Applicative to combine independent checks
  • A data processing pipeline using Monad to chain dependent operations
  • An error handling workflow using Either and Validated for robust failure management
  • A configuration system using Reader for dependency injection

From Optics Journeys

  • A user profile editor with deep nested updates using Lens composition
  • An e-commerce order processor using Traversals for bulk operations
  • A data validation pipeline combining Lens, Prism, and Traversal
  • A multi-step workflow builder using the Free Monad DSL with logging and validation

Tips for Success

  1. One journey per sitting. Each journey builds internal momentum. Splitting them reduces learning.
  2. Read hints in order. Nudge first, then Strategy, then Spoiler. Stop the moment we have enough.
  3. Run tests frequently. Get one green before moving on; don't write all the exercises in one go.
  4. Experiment fearlessly. Tests provide a safety net; we cannot break anything.
  5. Don't rush. Understanding matters more than speed. Take breaks between journeys.
  6. Ask questions. Use GitHub Discussions if a concept is unclear.

Beyond the Tutorials

After completing the tutorials, continue with:

  • Example Code — production-quality examples in hkj-examples, including the order, market, payment, and draughts domains
  • API Documentation — deep dives into every optic and typeclass
  • Complete Walkthroughs — how the patterns combine in real applications
  • One Line, Six Layers — the chapter-wide anchor that ties everything in this book to a single expression
  • Our own projects — apply these patterns to a real codebase

Ready to Begin?

Choose a starting point:

Recommended Path:

  1. Tutorial00 — One Line, Six Layers (anchor + setup check)
  2. Foundations Journey - core concepts
  3. Effect API Journey - the primary user-facing API

Core Types Track (Foundation):

Expression Track:

Concurrency & Resilience Track:

Optics Track:

Or see Learning Paths for detailed sequences.

Remember: the goal isn't to memorise every detail. It's to develop an intuition for when and how to apply these patterns. That only comes through practice.


Previous: Introduction Next: Core Types: Foundations Journey