TypeClass<F>Base interface for type classes that work with Higher-Kinded Types.
When to use
Use to define type class interfaces parameterized by a TypeLambda.
Details
A TypeClass defines operations that can be performed on any type constructor
that matches the given TypeLambda. This enables writing generic code that
works across different container types like Array, Option, Effect, etc.
Example (Defining higher-kinded type classes)
import type { HKT } from "effect"
// Define a Functor type class
interface Functor<F extends HKT.TypeLambda> extends HKT.TypeClass<F> {
map<A, B>(
fa: HKT.Kind<F, never, never, never, A>,
f: (a: A) => B
): HKT.Kind<F, never, never, never, B>
}
// Define a Monad type class
interface Monad<F extends HKT.TypeLambda> extends Functor<F> {
flatMap<A, B>(
fa: HKT.Kind<F, never, never, never, A>,
f: (a: A) => HKT.Kind<F, never, never, never, B>
): HKT.Kind<F, never, never, never, B>
}export interface interface TypeClass<F extends TypeLambda>Base interface for type classes that work with Higher-Kinded Types.
When to use
Use to define type class interfaces parameterized by a TypeLambda.
Details
A TypeClass defines operations that can be performed on any type constructor
that matches the given TypeLambda. This enables writing generic code that
works across different container types like Array, Option, Effect, etc.
Example (Defining higher-kinded type classes)
import type { HKT } from "effect"
// Define a Functor type class
interface Functor<F extends HKT.TypeLambda> extends HKT.TypeClass<F> {
map<A, B>(
fa: HKT.Kind<F, never, never, never, A>,
f: (a: A) => B
): HKT.Kind<F, never, never, never, B>
}
// Define a Monad type class
interface Monad<F extends HKT.TypeLambda> extends Functor<F> {
flatMap<A, B>(
fa: HKT.Kind<F, never, never, never, A>,
f: (a: A) => HKT.Kind<F, never, never, never, B>
): HKT.Kind<F, never, never, never, B>
}
TypeClass<function (type parameter) F in TypeClass<F extends TypeLambda>F extends TypeLambda> {
readonly [const URI: typeof URIDefines the unique symbol used to associate TypeClass implementations with their TypeLambda.
When to use
Use when you need to define a custom type class that exposes the TypeLambda
it operates on.
Details
This symbol links a type class shape with its compile-time type lambda. It is
intended for type-class definitions and has no runtime behavior.
Example (Linking a type class to a type lambda)
import type { HKT } from "effect"
interface IdentityTypeLambda extends HKT.TypeLambda {
readonly type: this["Target"]
}
interface IdentityTypeClass extends HKT.TypeClass<IdentityTypeLambda> {
readonly [HKT.URI]?: IdentityTypeLambda
readonly of: <A>(value: A) => HKT.Kind<IdentityTypeLambda, never, never, never, A>
}
const identity: IdentityTypeClass = {
of: (value) => value
}
type LinkedTypeLambda = typeof identity[typeof HKT.URI]
const value: HKT.Kind<NonNullable<LinkedTypeLambda>, never, never, never, string> = identity.of("ok")
console.log(value) // "ok"
URI]?: function (type parameter) F in TypeClass<F extends TypeLambda>F
}