Can I return my own PromiseLike type from async await function?

Viewed 228

I am trying to make a state monad in typescript, the implementation is roughly like this:

  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;
    ...
}

This implementation works fine if I only use method chaining, but I also want to use aysnc/await syntax to simulate the do notation in Haskell. What I want to achieve is this:


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);
}

I want f to return a State<S, A>, but that requires me to overload return somehow. Is there any way I can achieve the effect?

0 Answers
Related