or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

async-programming.mdcharacter-operations.mdcollections.mdconfiguration.mdcore-infrastructure.mddata-encoding.mddate-time.mdexternal-integration.mdindex.mdnumeric-types.mdreactive-programming.mdstring-operations.mdtype-system.md
tile.json

core-infrastructure.mddocs/

Core Infrastructure

Foundation types, utilities, and interfaces that underpin the entire Fable library. This module provides the essential building blocks for F# type system implementation in JavaScript.

Util Module - Core Utilities and Interfaces

The Util module provides core interfaces, utility functions, and foundational operations used throughout the library.

Interfaces

Comparison and Equality

// Core comparison interface
interface IComparer<T> {
    Compare(x: T, y: T): number;
}

// Object comparison capability
interface IComparable<T> {
    CompareTo(x: T): number;
}

// Equality comparison interface
interface IEqualityComparer<T> {
    Equals(x: T, y: T): boolean;
    GetHashCode(x: T): number;
}

// Object equality capability
interface IEquatable<T> {
    Equals(x: T): boolean;
}

Resource Management

// Disposable resource interface
interface IDisposable {
    Dispose(): void;
}

Date and Time

// Extended Date interface with kind
interface IDateTime extends Date {
    kind?: DateKind;
}

// DateTimeOffset interface
interface IDateTimeOffset extends Date {
    offset?: number;
}

// Date kind enumeration
enum DateKind {
    Unspecified = 0,
    UTC = 1,
    Local = 2
}

Core Classes

Comparer<T>

Generic comparer implementation with custom comparison functions.

class Comparer<T> implements IComparer<T> {
    constructor(f?: (x: T, y: T) => number);
    Compare(x: T, y: T): number;
}

// Usage
import { Comparer } from "fable-library/Util.js";

const stringComparer = new Comparer<string>((x, y) => x.localeCompare(y));
const result = stringComparer.Compare("apple", "banana"); // -1

Lazy<T>

Lazy evaluation implementation for deferred computation.

class Lazy<T> {
    constructor(factory: () => T);
    
    // Properties
    readonly Value: T; // Computed value (triggers evaluation)
    readonly IsValueCreated: boolean; // Whether value has been computed
    isValueCreated: boolean;
    factory: () => T;
}

// Usage
import { Lazy } from "fable-library/Util.js";

const lazyValue = new Lazy(() => {
    console.log("Computing...");
    return 42;
});

console.log(lazyValue.IsValueCreated); // false
console.log(lazyValue.Value); // "Computing..." then 42
console.log(lazyValue.IsValueCreated); // true

ObjectRef

Static utility for object reference management.

class ObjectRef {
    static id(o: any): number;
}

// Usage
import { ObjectRef } from "fable-library/Util.js";

const obj1 = { name: "test" };
const obj2 = { name: "test" };
console.log(ObjectRef.id(obj1)); // Unique ID
console.log(ObjectRef.id(obj2)); // Different ID

Utility Functions

Object and Extension

// Extend target object with sources
function extend(target: any, ...sources: any[]): any;

// Check if object implements IDisposable
function isDisposable(x: any): boolean;

// Create comparer from equality comparer
function comparerFromEqualityComparer<T>(comparer: IEqualityComparer<T>): Comparer<T>;

// Usage
import { extend, isDisposable } from "fable-library/Util.js";

const target = { a: 1 };
const source = { b: 2, c: 3 };
const result = extend(target, source); // { a: 1, b: 2, c: 3 }

Collection Utilities

// Check if Map contains value
function containsValue<K, V>(v: V, map: Map<K, V>): boolean;

// Try get value with default
function tryGetValue<K, V>(map: Map<K, V>, key: K, defaultValue: V): [boolean, V];

// Add value to Set, returns true if added
function addToSet<T>(v: T, set: Set<T>): boolean;

// Count items in iterable
function count<T>(col: Iterable<T>): number;

// Clear collection
function clear<T>(col: Iterable<T>): void;

// Dictionary operations
function addToDict<K, V>(dict: Map<K, V>, k: K, v: V): void;
function getItemFromDict<K, V>(map: Map<K, V>, key: K): V;

// Usage
import { containsValue, tryGetValue, count } from "fable-library/Util.js";

const map = new Map([["a", 1], ["b", 2]]);
console.log(containsValue(2, map)); // true

const [found, value] = tryGetValue(map, "c", 0);
console.log(found, value); // false, 0

console.log(count([1, 2, 3, 4])); // 4

Comparison and Equality

// Universal equality check
function equals(x: any, y: any): boolean;

// Universal comparison
function compare(x: any, y: any): number;

// Specialized comparisons
function compareDates(x: Date | IDateTime | IDateTimeOffset, y: Date | IDateTime | IDateTimeOffset): number;
function comparePrimitives(x: any, y: any): number;
function compareArrays<T>(x: ArrayLike<T>, y: ArrayLike<T>): number;
function compareArraysWith<T>(x: ArrayLike<T>, y: ArrayLike<T>, comp: (x: T, y: T) => number): number;
function compareObjects(x: { [k: string]: any }, y: { [k: string]: any }): number;

// Equality checks
function equalArrays<T>(x: ArrayLike<T>, y: ArrayLike<T>): boolean;
function equalArraysWith<T>(x: ArrayLike<T>, y: ArrayLike<T>, eq: (x: T, y: T) => boolean): boolean;

// Usage
import { equals, compare, equalArrays } from "fable-library/Util.js";

console.log(equals([1, 2, 3], [1, 2, 3])); // true
console.log(compare("apple", "banana")); // -1
console.log(equalArrays([1, 2], [1, 2])); // true

Hash Functions

// String hash computation
function stringHash(s: string): number;

// Number hash computation  
function numberHash(x: number): number;

// Combine multiple hash codes
function combineHashCodes(hashes: number[]): number;

// Identity-based hash
function identityHash(x: any): number;

// Structural hash (deep)
function structuralHash(x: any): number;

// Usage
import { stringHash, combineHashCodes, structuralHash } from "fable-library/Util.js";

const hash1 = stringHash("hello");
const hash2 = stringHash("world");
const combined = combineHashCodes([hash1, hash2]);

const objHash = structuralHash({ a: 1, b: [2, 3] });

Type Checking

// Check if value is array
function isArray(x: any): boolean;

// Check if value is iterable
function isIterable(x: any): boolean;

// Usage
import { isArray, isIterable } from "fable-library/Util.js";

console.log(isArray([1, 2, 3])); // true
console.log(isIterable("hello")); // true
console.log(isIterable(new Set())); // true

Mathematical Operations

// Rounding with precision
function round(value: number, digits?: number): number;

// Sign function
function sign(x: number): number;

// Random number generation
function randomNext(min: number, max: number): number;
function randomBytes(buffer: Uint8Array): void;

// Min/Max with custom comparer
function min<T>(comparer: (x: T, y: T) => number, x: T, y: T): T;
function max<T>(comparer: (x: T, y: T) => number, x: T, y: T): T;

// Usage
import { round, randomNext, min } from "fable-library/Util.js";

console.log(round(3.14159, 2)); // 3.14
console.log(randomNext(1, 10)); // Random number between 1-10

const minValue = min((x, y) => x - y, 5, 3); // 3

Functional Programming

// Ignore function (discard value)
function ignore(x: any): void;

// Atom creation (mutable reference)
function createAtom<T>(value: T): (v?: T) => T | void;

// Function currying/uncurrying (arity 2-8)
function uncurry(arity: number, f: Function): Function;
function curry(arity: number, f: Function): Function;
function partialApply(arity: number, f: Function, args: any[]): any;

// Usage
import { ignore, createAtom, curry } from "fable-library/Util.js";

ignore(someComputationResult); // Discard result

const atom = createAtom(42);
console.log(atom()); // 42
atom(100);
console.log(atom()); // 100

const add = (x: number, y: number) => x + y;
const curriedAdd = curry(2, add);
const add5 = curriedAdd(5);
console.log(add5(3)); // 8

Object Creation

// Create object from fields
function createObj(fields: Iterable<any>, caseRule?: number): { [k: string]: any };

// JavaScript options pattern
function jsOptions(mutator: (x: object) => void): object;

// Usage
import { createObj, jsOptions } from "fable-library/Util.js";

const obj = createObj([["name", "John"], ["age", 30]]);
// { name: "John", age: 30 }

const options = jsOptions(opt => {
    opt.timeout = 5000;
    opt.retries = 3;
});

String Encoding

// URI encoding/decoding
function unescapeDataString(s: string): string;
function escapeDataString(s: string): string;
function escapeUriString(s: string): string;

// Usage
import { escapeDataString, unescapeDataString } from "fable-library/Util.js";

const encoded = escapeDataString("hello world"); // "hello%20world"
const decoded = unescapeDataString(encoded); // "hello world"

Lazy Evaluation

// Create lazy value from computed value
function lazyFromValue<T>(v: T): Lazy<T>;

// Usage
import { lazyFromValue } from "fable-library/Util.js";

const lazy = lazyFromValue(42);
console.log(lazy.Value); // 42 (no computation)
console.log(lazy.IsValueCreated); // true

Date and Number Formatting

// Pad number with leading zeros
function padWithZeros(i: number, length: number): string;

// Pad number with zeros on both sides
function padLeftAndRightWithZeros(i: number, lengthLeft: number, lengthRight: number): string;

// Get offset from date objects
function dateOffset(date: IDateTime | IDateTimeOffset): number;

// Convert integers to string with radix support
function int16ToString(i: number, radix?: number): string;
function int32ToString(i: number, radix?: number): string;

// Usage
import { padWithZeros, int16ToString, dateOffset } from "fable-library/Util.js";

console.log(padWithZeros(42, 5)); // "00042"
console.log(int16ToString(255, 16)); // "ff"
console.log(int32ToString(-1, 16)); // "ffffffff"

// Date offset handling
const dateTime: IDateTime = new Date();
dateTime.kind = DateKind.Local;
const offset = dateOffset(dateTime); // Local timezone offset

Types Module - Core Type System

Fundamental types and classes for the F# type system implementation in JavaScript.

Base Classes

SystemObject

Base object type for all F# objects with universal operations.

class SystemObject {
    toString(): string;
    GetHashCode(): number;
    Equals(other: any): boolean;
}

// Usage
import { SystemObject } from "fable-library/Types.js";

class MyClass extends SystemObject {
    constructor(public value: number) {
        super();
    }
}

const obj = new MyClass(42);
console.log(obj.toString()); // Object representation
console.log(obj.GetHashCode()); // Hash code

List

F# immutable linked list implementation.

class List<T> extends SystemObject {
    constructor(head: T, tail: List<T> | null);
    
    toString(): string;
    toJSON(): T[];
    GetHashCode(): number;
    Equals(other: any): boolean;
    CompareTo(other: any): number;
    
    // Iterator support
    [Symbol.iterator](): Iterator<T>;
}

// Usage
import { List } from "fable-library/Types.js";

// Create list: [1, 2, 3]
const list = new List(1, new List(2, new List(3, null)));

// Iterate
for (const item of list) {
    console.log(item); // 1, 2, 3
}

// Convert to array
const array = list.toJSON(); // [1, 2, 3]

Union

F# discriminated union base class.

class Union extends SystemObject {
    constructor(tag: number, name: string, ...fields: any[]);
    
    tag: number;
    name: string;
    fields: any[];
    
    toString(): string;
    toJSON(): any;
    GetHashCode(): number;
    Equals(other: any): boolean;
    CompareTo(other: any): number;
}

// Usage - Custom union type
import { Union } from "fable-library/Types.js";

class Shape extends Union {
    static Circle(radius: number): Shape {
        return new Shape(0, "Circle", radius);
    }
    
    static Rectangle(width: number, height: number): Shape {
        return new Shape(1, "Rectangle", width, height);
    }
}

const circle = Shape.Circle(5);
const rect = Shape.Rectangle(10, 20);

console.log(circle.tag); // 0
console.log(circle.name); // "Circle"
console.log(circle.fields); // [5]

Record

F# record base type with structural equality.

class Record extends SystemObject {
    toString(): string;
    toJSON(): any;
    GetHashCode(): number;
    Equals(other: any): boolean;
    CompareTo(other: any): number;
}

// Usage - Custom record type
import { Record } from "fable-library/Types.js";

class Person extends Record {
    constructor(public name: string, public age: number) {
        super();
    }
}

const person1 = new Person("John", 30);
const person2 = new Person("John", 30);

console.log(person1.Equals(person2)); // true (structural equality)

FSharpRef

F# reference cell for mutable references.

class FSharpRef<T> {
    constructor(contents: T);
    contents: T;
}

// Usage
import { FSharpRef } from "fable-library/Types.js";

const ref = new FSharpRef(42);
console.log(ref.contents); // 42

ref.contents = 100;
console.log(ref.contents); // 100

Exception Types

Exception

Base exception type for error handling.

class Exception extends Error {
    constructor(msg?: string);
    stack: string;
    message: string;
}

// Usage
import { Exception } from "fable-library/Types.js";

throw new Exception("Something went wrong");

FSharpException

F# exception base with F# object capabilities.

class FSharpException extends Exception {
    toString(): string;
    toJSON(): any;
    GetHashCode(): number;
    Equals(other: any): boolean;
    CompareTo(other: any): number;
}

MatchFailureException

Specialized exception for pattern match failures.

class MatchFailureException extends FSharpException {
    constructor(arg1: any, arg2: number, arg3: number);
    
    arg1: any;      // Source file/expression
    arg2: number;   // Line number
    arg3: number;   // Column number
    message: string;
}

// Usage - thrown by generated F# pattern matching code
import { MatchFailureException } from "fable-library/Types.js";

// This would be generated by F# compiler
function matchValue(x: any): string {
    if (x.tag === 0) return "Case0";
    if (x.tag === 1) return "Case1";
    throw new MatchFailureException("pattern.fs", 10, 5);
}

Attribute

Base attribute type for F# attributes.

class Attribute extends SystemObject {}

// Usage - Custom attribute
import { Attribute } from "fable-library/Types.js";

class ObsoleteAttribute extends Attribute {
    constructor(public message?: string) {
        super();
    }
}

Utility Functions

// Declare F# type with inheritance
function declare(cons: Function, superClass?: Function): Function;

// Create anonymous record
function anonRecord(o: any): any;

// Check if value is exception
function isException(x: any): boolean;

// Usage
import { declare, anonRecord, isException } from "fable-library/Types.js";

// Anonymous record
const record = anonRecord({ name: "John", age: 30 });

// Check exception
console.log(isException(new Error())); // true
console.log(isException("not an error")); // false

Option Module - Option and Choice Types

F# option, choice, and result type implementations providing safe null handling and error management.

Option Type

Some Class

Wrapper for non-null optional values.

class Some<T> {
    constructor(value: T);
    value: T;
    
    toString(): string;
    toJSON(): T;
    GetHashCode(): number;
    Equals(other: any): boolean;
    CompareTo(other: any): number;
}

// Usage
import { Some } from "fable-library/Option.js";

const someValue = new Some(42);
console.log(someValue.value); // 42
console.log(someValue.toString()); // "Some(42)"

Option Functions

// Create Some value
function some<T>(x: T): Some<T> | null;

// Extract value from option
function value<T>(x: Some<T> | null, acceptNull?: boolean): T;

// Provide default value for None
function defaultArg<T>(arg: Some<T> | null, defaultValue: T, f?: Function): T;

// Provide default value via thunk
function defaultArgWith<T>(arg: Some<T> | null, defThunk: () => T): T;

// Filter option based on predicate
function filter<T>(predicate: (x: T) => boolean, arg: Some<T> | null): Some<T> | null;

// Usage
import { some, value, defaultArg, filter } from "fable-library/Option.js";

const opt1 = some(42);
const opt2 = null; // None

console.log(value(opt1)); // 42
// console.log(value(opt2)); // Would throw

console.log(defaultArg(opt1, 0)); // 42
console.log(defaultArg(opt2, 0)); // 0

const filtered = filter(x => x > 40, opt1); // Some(42)
const filtered2 = filter(x => x > 50, opt1); // null (None)

Choice Type

F# choice type for handling multiple possible value types.

class Choice extends Union {
    constructor(tag: number, name: string, field: any);
}

// Choice creation functions
function choice1<T>(x: T): Choice; // Choice1Of2
function choice2<T>(x: T): Choice; // Choice2Of2

// Choice extraction functions
function tryValueIfChoice1(x: Choice): any;
function tryValueIfChoice2(x: Choice): any;

// Usage
import { choice1, choice2, tryValueIfChoice1, tryValueIfChoice2 } from "fable-library/Option.js";

// Create choices
const success = choice1("Operation succeeded");
const error = choice2(new Error("Operation failed"));

// Extract values
const successValue = tryValueIfChoice1(success); // "Operation succeeded"
const errorValue = tryValueIfChoice2(error);     // Error object

console.log(tryValueIfChoice1(error)); // null
console.log(tryValueIfChoice2(success)); // null

Result Type

F# result type for error handling with Ok/Error cases.

class Result extends Union {
    constructor(tag: number, name: string, field: any);
}

// Result creation functions
function ok<T>(x: T): Result;       // Ok case
function error<T>(x: T): Result;    // Error case

// Result transformation functions
function mapOk<T, U>(f: (x: T) => U, result: Result): Result;
function mapError<T, U>(f: (x: T) => U, result: Result): Result;
function bindOk<T, U>(f: (x: T) => Result, result: Result): Result;

// Usage
import { ok, error, mapOk, mapError, bindOk } from "fable-library/Option.js";

// Create results
const successResult = ok(42);
const errorResult = error("Something went wrong");

// Transform Ok values
const doubled = mapOk(x => x * 2, successResult); // Ok(84)
const stillError = mapOk(x => x * 2, errorResult); // Still Error

// Transform Error values  
const betterError = mapError(msg => `Error: ${msg}`, errorResult);

// Chain operations (only if Ok)
const chained = bindOk(x => {
    if (x > 40) return ok(x.toString());
    else return error("Value too small");
}, successResult); // Ok("42")

Integration Examples

Working with Nullable Values

import { some, value, defaultArg } from "fable-library/Option.js";

// Convert nullable to option
function toOption<T>(nullable: T | null | undefined): Some<T> | null {
    return nullable != null ? some(nullable) : null;
}

// Safe dictionary lookup
function safeDictLookup<K, V>(dict: Map<K, V>, key: K): Some<V> | null {
    return dict.has(key) ? some(dict.get(key)!) : null;
}

// Chain operations safely
const dict = new Map([["a", 1], ["b", 2]]);
const result = safeDictLookup(dict, "a");
const doubled = result ? some(value(result) * 2) : null;
console.log(doubled ? value(doubled) : 0); // 2

Error Handling Pipeline

import { ok, error, bindOk, mapOk } from "fable-library/Option.js";

// Pipeline of operations that can fail
function divide(x: number, y: number): Result {
    return y !== 0 ? ok(x / y) : error("Division by zero");
}

function sqrt(x: number): Result {
    return x >= 0 ? ok(Math.sqrt(x)) : error("Negative number");
}

// Chain operations
const result = bindOk(x => sqrt(x), divide(16, 4)); // Ok(2)
const error_result = bindOk(x => sqrt(x), divide(16, 0)); // Error("Division by zero")
const error_result2 = bindOk(x => sqrt(x), divide(-16, 4)); // Error("Negative number")