Skip to content

State

State: object

Defined in: Core/State.ts:27

apply: <S, A>(arg) => <B>(state) => 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>(state) => State<S, B>

chain to sequence dependent State transitions.

const addCounted = (n: number) => (m: number) => n + m;
const program = pipe(
  State.make<number, typeof addCounted>(addCounted),
  State.apply(pipe(State.get<number>(), State.map((s) => s * 2))),
  State.apply(State.get<number>()),
);

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

assign: <K, S, A, B>(key, transform) => (state) => 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

(value) => State<S, B>

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

assignTo to initialize the accumulator record.

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

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

Lifts a State value into an accumulator object.

K extends string

K

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

assign to accumulate subsequent State values into the object.

pipe(State.make(42), State.assignTo("value")); // State({ value: 42 })

chain: <A, S, B>(transform) => (state) => 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.

A

S

B

(value) => State<S, B>

(state) => State<S, B>

map to transform the produced value without changing the state transition.

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>(state) => A

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

S

S

<A>(state) => A

run to obtain both the value and final state, or execute for only the state.

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

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

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

S

S

<A>(state) => S

run to obtain both the value and final state, or evaluate for only the value.

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

focus: <S, SubState>(lens) => <A>(state) => State<S, A>

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

S

SubState

Lens<S, SubState>

<A>(state) => State<S, A>

modify to update state directly without a Lens.

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>

put to replace the state, or modify to transform it with a function.

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

make: <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>

get to produce the current state instead of a static value.

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

map: <A, B>(transform) => <S>(state) => State<S, B> = mapState

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

A

B

(value) => B

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

chain to sequence a computation that produces a new State.

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>(transform) => State<S, undefined>

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

S

(state) => S

State<S, undefined>

put to replace the state with a constant value, or get to read it.

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>

get to read the current state, or modify to transform it.

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

run: <S>(initialState) => <A>(state) => 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>(state) => readonly [A, S]

evaluate to discard the final state, or execute to discard the produced value.

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

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

tap: <A>(sideEffect) => <S>(state) => State<S, A>

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

A

(value) => void

<S>(state) => State<S, A>

map to transform the value instead of executing a side effect.

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