An educational implementation of typeclass-oriented functional programming in modern Java.
Milestone 0.5.0 introduces a minimal higher-kinded type (HKT) encoding on top of the ADT and algebra layers completed in 0.4.1.
The project demonstrates how concepts associated with Scala, Cats and Haskell can be represented explicitly in Java while keeping the implementation small and understandable.
The project currently covers:
- explicit typeclass instances and dictionary passing,
Eq,Ord,Show,SemigroupandMonoid,- executable algebraic laws and jqwik property tests,
- sealed ADTs:
Option,EitherandValidated, - compositional
EqandShowinstances, NonEmptyList<A>and lawful concatenationSemigroup,- smart constructors, typed validation errors and domain invariants,
- a minimal HKT encoding through
Kind<F,A>, - witness types and partial type application,
- centralized widen/narrow helpers.
The project deliberately does not yet introduce Functor, Applicative, Monad, Traverse, effect types, Kleisli, Tagless Final, Free Monad or optics.
- Java 21 or newer,
- Gradle 9.8.0 through the wrapper configuration.
CI is intended to verify Java 21, 25 and 27.
./gradlew clean check
./gradlew javadocsrc/main/java/io/codeswarm/typeclasses/
├── algebra/
│ ├── Monoid.java
│ └── Semigroup.java
├── core/
│ ├── Eq.java
│ ├── Ord.java
│ └── Show.java
├── hkt/
│ ├── Kind.java
│ └── package-info.java
├── data/
│ ├── Option.java
│ ├── OptionK.java
│ ├── OptionKinds.java
│ ├── Some.java
│ ├── None.java
│ ├── Either.java
│ ├── EitherK.java
│ ├── EitherKinds.java
│ ├── Left.java
│ ├── Right.java
│ ├── Validated.java
│ ├── ValidatedK.java
│ ├── ValidatedKinds.java
│ ├── Valid.java
│ ├── Invalid.java
│ └── NonEmptyList.java
├── domain/
├── examples/
├── instances/
└── syntax/
Reusable law helpers remain in src/test/java/io/codeswarm/typeclasses/laws/.
Java can abstract over values of type A, but cannot directly abstract over a type constructor like Scala's F[_]. Milestone 0.5 introduces:
public interface Kind<F, A> {
}The F parameter is a witness identifying the constructor.
Option<A> now implements:
Kind<OptionK, A>
Example:
Option<Integer> option = Option.some(42);
Kind<OptionK, Integer> widened = OptionKinds.widen(option);
Option<Integer> restored = OptionKinds.narrow(widened);Either<L,R> has two type parameters, but a future Functor<F> needs a unary constructor. The left type is therefore fixed in a witness:
Either<String, Integer>
≈ Kind<EitherK<String>, Integer>
Likewise:
Validated<String, Integer>
≈ Kind<ValidatedK<String>, Integer>
This models partial type application without adding wrapper objects around the ADTs.
widen requires no cast because each ADT directly implements the relevant Kind application.
narrow needs a controlled unchecked cast because Java type erasure cannot prove the witness-to-ADT relationship at runtime. Those casts are intentionally isolated in exactly three helpers:
OptionKinds.narrow,EitherKinds.narrow,ValidatedKinds.narrow.
The rest of the codebase should not perform HKT-related unchecked casts.
See docs/HKT.md.
Milestone 0.5 preserves the 0.4.1 APIs:
NonEmptyList<A>models non-empty collections structurally,Invalid<E,A>storesNonEmptyList<E>,UserId,PersonNameandAgeuse smart constructors,ValidationErroris a sealed typed error hierarchy,UserValidatordemonstrates domain-level error accumulation withValidated.
No monadic API is added to those types yet.
- SRP — HKT mechanics live in
hktand*Kindshelpers rather than inside unrelated typeclasses. - OCP — new type constructors can participate by introducing their own witness and
Kindimplementation. - DIP — future higher-order typeclasses can depend on
Kind<F,A>instead of concrete ADTs. - KISS — only one marker abstraction is introduced; there is no
Kind2, registry or reflection layer. - DRY — unavoidable casts are centralized instead of repeated across future typeclass instances.
- YAGNI —
Functor,ApplicativeandMonadremain outside this milestone.
HktExample demonstrates round-trip widening and narrowing for Option, Either and Validated.
Existing examples continue to demonstrate algebra, ADTs, smart constructors and validation.
- Architecture
- Typeclasses
- Algebra
- Algebraic laws
- Algebraic data types
- Smart constructors
- Higher-kinded type encoding
- Implementation tasks
- Roadmap
- Changelog
0.6 Functor / Applicative / Monad / MonadError
0.7 Foldable / Traverse / Bifunctor
0.8 Id / Eval / IO / FunctionK
0.9 Kleisli and effectful composition
0.10 Tagless Final
0.11 Free Monad
0.12 Lens / Prism / Optics
0.13+ advanced typeclasses, derivation and API hardening
1.0 stable educational release
Apache License 2.0. See LICENSE.