Complete overview of data structures and interfaces
Explore which functional programming interfaces are supported by each data structure in functype
This matrix shows which interfaces are supported by each data structure in the functype library.
All base typeclasses (Traversable, Extractable, Functor, Applicative, Monad, AsyncMonad, ContainerOps, CollectionOps, Foldable, Serializable, Pipe, Matchable, Promisable, Doable, Reshapeable) declared <out T> / <out A>.
Traversable.reduce / reduceRight are guarded by Widen<A, B> (src/typeclass/variance.ts), TypeScript’s equivalent of Scala’s [B >: A] lower-bound constraint. See variance-guide.md for the full contributor reference.
Collections (List, Set, LazyList, Stack, Map, Obj) keep Traversable. Sum types (Either, Try) extend the lighter FunctypeSum base with no collection-style methods.
All types follow the Companion pattern (inspired by Scala), combining constructor functions with static utility methods. Each type provides:
Collection creation - multiple options available:
// List creation
List([1, 2, 3]) // from array
List.of(1, 2, 3) // variadic factory
List.empty<number>() // typed empty list
// Set creation
Set([1, 2, 3]) // from array
Set.of(1, 2, 3) // variadic factory
Set.empty<number>() // typed empty set
// Map creation
Map([
["a", 1],
["b", 2],
]) // from key-value pairs
Map.of<string, number>(["a", 1], ["b", 2]) // variadic factory
Map.empty<string, number>() // typed empty map
// Http — fetch wrapper returning IO<never, HttpError, HttpResponse<unknown>> by default
// Provide a validate function to get typed responses (BYOV: bring your own validator)
Http.get(url, opts?) // GET → HttpResponse<unknown>
Http.get(url, { validate }) // GET → HttpResponse<T> (T inferred from validate)
Http.post(url, opts?) // POST with auto JSON body serialization
Http.put(url, opts?) // PUT
Http.patch(url, opts?) // PATCH
Http.delete(url, opts?) // DELETE
Http.request(fullOpts) // Full control
Http.client(config) // Create configured client with baseUrl, defaultHeaders, custom fetch
// Example with validator (works with Zod, TypeBox, Valibot, or manual validators)
Http.get("/api/users", { validate: (data) => z.array(UserSchema).parse(data) })
Http.post("/api/users", { body: { name: "Alice" }, validate: (data) => UserSchema.parse(data) })
// HttpError — three-variant ADT
HttpError.networkError(url, method, cause)
HttpError.httpStatusError(url, method, status, statusText, body)
HttpError.decodeError(url, method, body, cause)
HttpError.match(error, { NetworkError, HttpStatusError, DecodeError })
HttpError.isNetworkError(e) / .isHttpStatusError(e) / .isDecodeError(e)
Static type guards for narrowing types:
| Data Structure | Type Guard Methods |
|---|---|
| Option | isSome(option), isNone(option) |
| Either<L,R> | isLeft(either), isRight(either) |
| Try | isSuccess(tryValue), isFailure(tryValue) |
All Serializable types provide static deserialization methods:
fromJSON(json: string): T - Deserialize from JSONfromYAML(yaml: string): T - Deserialize from YAMLfromBinary(binary: string): T - Deserialize from base64-encoded binaryNote: See docs/companion-pattern.md for complete guide on the Companion pattern.
map<B>(f: (value: A) => B): Functor<B>ap<B>(ff: Applicative<(value: A) => B>): Applicative<B>flatMap<B>(f: (value: A) => Monad<B>): Monad<B>flatMapAsync<B>(f: (value: A) => PromiseLike<AsyncMonad<B>>): PromiseLike<AsyncMonad<B>>foldLeft<B>(z: B): (op: (b: B, a: A) => B) => BfoldRight<B>(z: B): (op: (a: A, b: B) => B) => BNote: fold has different semantics per type category:
fold<B>(onEmpty: () => B, onValue: (value: A) => B): B — pattern matchfold<B>(initial: B, fn: (acc: B, a: A) => B): B — left-reduce accumulatorfoldAsync (Option, Either, Try) — same shape as fold but accepts sync or async handlers and always returns Promise<B>. Use when at least one branch performs async work to avoid T | Promise<T> unions.
match<R>(patterns: Record<Tags, (value: A) => R>): Rserialize(): SerializationMethods<T>
toJSON(): stringtoYAML(): stringtoBinary(): Uint8Arraysize: numberisEmpty: booleancontains(value: A): booleanreduce<B>(f: (acc: B, value: A) => B, initial: B): BreduceRight<B>(f: (value: A, acc: B) => B, initial: B): BorThrow(error?: Error): TorElse(defaultValue: T): Tor(alternative: Extractable<T>): Extractable<T>orNull(): T | nullorUndefined(): T | undefinedpipe<U>(f: (value: T) => U): UtoList(): List<A>toSet(): Set<A>toString(): stringcount(p: (value: A) => boolean): numberfind(p: (value: A) => boolean): A | undefinedexists(p: (value: A) => boolean): booleanforEach(f: (value: A) => void): voiddrop(n: number): SelfdropRight(n: number): SelfdropWhile(p: (value: A) => boolean): Selfflatten(): Selfhead: A | undefinedheadOption: Option<A>take(n: number): SelftakeWhile(p: (value: A) => boolean): SelftakeRight(n: number): Selflast: A | undefinedlastOption: Option<A>tail: Selfinit: SelftoArray(): A[]reverse(): List<A>indexOf(value: A): numberprepend(item: A): List<A>distinct(): List<A>sorted(compareFn?): List<A>sortBy(f, compareFn?): List<A>zip(other: List<B>): List<[A, B]>zipWithIndex(): List<[A, number]>groupBy(f: (a: A) => K): Map<K, List<A>>partition(p): [List<A>, List<A>]span(p): [List<A>, List<A>]slice(start, end): List<A>Enables Scala-like for-comprehensions using JavaScript generators:
Do(function* () { ... }): Synchronous monadic comprehensionsDoAsync(async function* () { ... }): Async monadic comprehensions$(monad): Helper for type inference with yield*Provides type conversion between monadic types:
toOption(): Option<T>toEither<E>(leftValue: E): Either<E, T>toList(): List<T>toTry(): Try<T>Provides conversion to Promise for async interop:
toPromise(): Promise<T>Functype<A, Tag>: Implemented by single-value containers (Option, Try, Lazy). Provides full functional programming support.
FunctypeCollection<A, Tag>: Implemented by collection containers (List, Set). Extends FunctypeBase with collection-specific operations.
Special Cases:
Do-notation: Provides generator-based monadic comprehensions similar to Scala’s for-comprehensions. Supports Option, Either, Try, and List with automatic short-circuiting and cartesian products.
Reshapeable: Enables conversion between different monad types, allowing flexible composition in Do-notation when mixing types.
Promisable: Provides conversion to Promise for async interoperability. Supported by Option, Either, Try, and TaskOutcome.
Utility Types (not in matrix):
IO<R,E,A>: Lazy, composable effect type with typed errors and dependency injection.
IO.gen) and builder do-notation (IO.Do)