我正在尝试在打字稿中创建状态单子,实现大致如下:
export class State<S, A> implements PromiseLike<A> {
readonly [Symbol.toStringTag] = "StateMoand";
runState: RunState<S, A>;
...
constructor(runState: RunState<S, A>) {
this.runState = runState;
...
}
static pure<S, A>(a: A): State<S, A> {
return new State<S, A>(s => [a, s]);
}
bind<B>(f: (a: A) => State<S, B>) {
const runState: RunState<S, B> = (s: S) => {
const [a, s1] = this.runState(s);
return f(a).runState(s1);
}
return new State(runState);
}
then = this.bind;
...
}
如果我仅使用方法链接,但我也想使用aysnc/await
语法来模拟Haskell中的do notation
,则此实现效果很好。我要实现的是这样:
it("then", async () => {
const state = new State<string, number>(s => {
return [Number.parseInt(s), s + "0"];
});
const f = async (state: State<string, number>) => {
const p = await state.get();
await state.put("11");
await state.modify(s => s + "22");
return p;
}
await f(state);
}
我希望f
返回一个State<S, A>
,但这需要我以某种方式重载return
。有什么办法可以达到效果?