Skip to content

State

State: object

Defined in: Core/State.ts:27

ap: <S, A>(arg) => <B>(fn) => State<S, B>

Applies a function wrapped in a State to a value wrapped in a State. The function computation runs first; its output state is the input to the argument computation.

S

A

State<S, A>

<B>(fn) => State<S, B>

const addCounted = (n: number) => (m: number) => n + m;
const program = pipe(
  State.resolve<number, typeof addCounted>(addCounted),
  State.ap(State.gets((s: number) => s * 2)),
  State.ap(State.gets((s: number) => s)),
);

State.evaluate(3)(program); // 6 + 3 = 9

bind: <K, S, A, B>(key, f) => (data) => State<S, A & { [P in string]: B }>

Evaluates a new State using the current accumulator and attaches the output to a new key.

K extends string

S

A

B

K

(a) => State<S, B>

(data) => State<S, A & { [P in string]: B }>

pipe(
  State.resolve({ a: 1 }),
  State.bind("b", ({ a }) => State.resolve(a + 1))
); // State({ a: 1, b: 2 })

bindTo: <K>(key) => <S, A>(data) => State<S, { [P in string]: A }>

Lifts a State value into an accumulator object.

K extends string

K

<S, A>(data) => State<S, { [P in string]: A }>

pipe(State.resolve(42), State.bindTo("value")); // State({ value: 42 })

chain: <S, A, B>(f) => (st) => State<S, B> = chainState

Sequences two State computations. The state output of the first is passed as the state input to the second.

Data-last — the first computation is the data being piped.

S

A

B

(a) => State<S, B>

(st) => State<S, B>

const push = (item: string): State<string[], undefined> =>
  State.modify(stack => [...stack, item]);

const program = pipe(
  push("a"),
  State.chain(() => push("b")),
  State.chain(() => State.get<string[]>()),
);

State.evaluate([])(program); // ["a", "b"]

evaluate: <S>(initialState) => <A>(st) => A

Runs a State computation with an initial state, returning only the produced value (discarding the final state).

S

S

<A>(st) => A

State.evaluate([])(pipe(
  State.modify<string[]>(s => [...s, "x"]),
  State.chain(() => State.get<string[]>()),
)); // ["x"]

execute: <S>(initialState) => <A>(st) => S

Runs a State computation with an initial state, returning only the final state (discarding the produced value).

S

S

<A>(st) => S

State.execute(0)(pipe(
  State.modify<number>(n => n + 10),
  State.chain(() => State.modify<number>(n => n * 2)),
)); // 20

focus: <S, A>(lens) => <B>(stateOp) => State<S, B>

Focuses a State computation on a sub-state using a Lens.

S

A

Lens<S, A>

<B>(stateOp) => State<S, B>

type AppState = { count: number; name: string };
const countLens = Lens.from.property<AppState>()("count");
const increment = State.modify((c: number) => c + 1);
const focusedProgram = pipe(increment, State.focus(countLens));

get: <S>() => State<S, S>

Produces the current state as the value, without modifying it.

S

State<S, S>

const readStack: State<string[], string[]> = State.get();
State.run(["a", "b"])(readStack); // [["a", "b"], ["a", "b"]]

gets: <S, A>(f) => State<S, A>

Reads a projection of the state without modifying it. Equivalent to pipe(State.get(), State.map(f)) but more direct.

S

A

(s) => A

State<S, A>

type AppState = { count: number; label: string };
const readCount: State<AppState, number> = State.gets(s => s.count);
State.run({ count: 5, label: "x" })(readCount); // [5, { count: 5, label: "x" }]

map: <S, A, B>(f) => (st) => State<S, B> = mapState

Transforms the value produced by a State computation. The state transformation is unchanged.

S

A

B

(a) => B

(st) => State<S, B>

const readLength: State<string[], number> = pipe(
  State.get<string[]>(),
  State.map(stack => stack.length),
);

State.run(["a", "b", "c"])(readLength); // [3, ["a", "b", "c"]]

modify: <S>(f) => State<S, undefined>

Applies a function to the current state to produce the next state. Produces no meaningful value.

S

(s) => S

State<S, undefined>

const push = (item: string): State<string[], undefined> =>
  State.modify(stack => [...stack, item]);

State.run(["a"])(push("b")); // [undefined, ["a", "b"]]

put: <S>(newState) => State<S, undefined>

Replaces the current state with a new value. Produces no meaningful value.

S

S

State<S, undefined>

const reset: State<number, undefined> = State.put(0);
State.run(99)(reset); // [undefined, 0]

resolve: <S, A>(value) => State<S, A>

Lifts a pure value into a State computation. The state passes through unchanged.

S

A

A

State<S, A>

State.run(10)(State.resolve(42)); // [42, 10] — value 42, state unchanged

run: <S>(initialState) => <A>(st) => readonly [A, S]

Runs a State computation with an initial state, returning both the produced value and the final state as a pair.

Data-last — the computation is the data being piped.

S

S

<A>(st) => readonly [A, S]

const program = pipe(
  State.modify<number>(n => n + 1),
  State.chain(() => State.get<number>()),
);

State.run(0)(program); // [1, 1]

tap: <S, A>(f) => (st) => State<S, A>

Runs a side effect on the produced value without changing the State computation.

S

A

(a) => void

(st) => State<S, A>

pipe(
  State.get<number>(),
  State.tap(n => console.log("current:", n)),
  State.chain(() => State.modify(n => n + 1)),
);