com.github.tonivade.purefun.monad.State Maven / Gradle / Ivy
/*
* Copyright (c) 2018-2019, 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.Operator1;
import com.github.tonivade.purefun.Tuple2;
import com.github.tonivade.purefun.Unit;
import com.github.tonivade.purefun.data.Sequence;
@HigherKind
@FunctionalInterface
public interface State {
Tuple2 run(S state);
default State map(Function1 mapper) {
return flatMap(value -> pure(mapper.apply(value)));
}
default State flatMap(Function1> mapper) {
return state -> {
Tuple2 run = run(state);
return mapper.apply(run.get2()).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 mapper) {
return state -> Tuple2.of(state, mapper.apply(state));
}
static State> compose(Sequence> states) {
return states.foldLeft(pure(empty()), (sa, sb) -> map2(sa, sb, (acc, a) -> acc.append(a)));
}
static State map2(State sa, State sb, Function2 mapper) {
return sa.flatMap(a -> sb.map(b -> mapper.curried().apply(a).apply(b)));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy