com.github.tonivade.purefun.monad.State Maven / Gradle / Ivy
/*
* Copyright (c) 2018-2023, Antonio Gabriel Muñoz Conejo
* Distributed under the terms of the MIT License
*/
package com.github.tonivade.purefun.monad;
import static com.github.tonivade.purefun.Unit.unit;
import static com.github.tonivade.purefun.data.ImmutableList.empty;
import com.github.tonivade.purefun.Function1;
import com.github.tonivade.purefun.Function2;
import com.github.tonivade.purefun.HigherKind;
import com.github.tonivade.purefun.Kind;
import com.github.tonivade.purefun.Bindable;
import com.github.tonivade.purefun.Operator1;
import com.github.tonivade.purefun.Tuple2;
import com.github.tonivade.purefun.Unit;
import com.github.tonivade.purefun.data.Sequence;
@HigherKind
@FunctionalInterface
public non-sealed interface State extends StateOf, Bindable, A> {
Tuple2 run(S state);
@Override
default State map(Function1 super A, ? extends R> mapper) {
return flatMap(value -> pure(mapper.apply(value)));
}
@Override
default State flatMap(Function1 super A, ? extends Kind, ? extends R>> mapper) {
return state -> {
Tuple2 run = run(state);
State narrowK = mapper.andThen(StateOf::narrowK).apply(run.get2());
return narrowK.run(run.get1());
};
}
default A eval(S state) {
return run(state).get2();
}
static State state(Function1> runState) {
return runState::apply;
}
static State pure(A value) {
return state -> Tuple2.of(state, value);
}
static State get() {
return state -> Tuple2.of(state, state);
}
static State set(S value) {
return state -> Tuple2.of(value, unit());
}
static State modify(Operator1 mapper) {
return state -> Tuple2.of(mapper.apply(state), unit());
}
static State inspect(Function1 super S, ? extends A> mapper) {
return state -> Tuple2.of(state, mapper.apply(state));
}
static State> traverse(Sequence> states) {
return states.foldLeft(pure(empty()),
(State>sa, State sb) -> map2(sa, sb, Sequence::append));
}
static State map2(State sa, State sb,
Function2 super A, ? super B, ? extends C> mapper) {
return sa.flatMap(a -> sb.map(b -> mapper.curried().apply(a).apply(b)));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy