State Monad in TypeScript Here's my implementation of State Monad in TypeScript, based on a canonical Haskell implementation.
I would like it to get code reviewed.

class StateMonad&lt;S, A&gt; {
  constructor(public runState: (s: S) =&gt; ({ s: S, a: A })) {
  }

  static return_&lt;S, A&gt;(a: A): StateMonad&lt;S, A&gt; {
    return new StateMonad(s =&gt; ({ s, a }));
  }

  bind&lt;B&gt;(func: (a: A) =&gt; StateMonad&lt;S, B&gt;): StateMonad&lt;S, B&gt; {
    return new StateMonad&lt;S, B&gt;((s: S) =&gt; {
      const { s: s_, a } = this.runState(s);
      return func(a).runState(s_);
    });
  }
}

// aux monad factory
const createCounter = (regex: RegExp) =&gt; new StateMonad((s: string) =&gt;
  s.split('')
    .reduce((acc, c) =&gt;
      (regex.test(c)) ? { s: acc.s.replace(c, ''), a: acc.a + 1 } : acc,
      { s, a: 0 })
);

const countLowerCase = createCounter(/[a-z]/);
const countDigits = createCounter(/[0-9]/);


// usage example
const { a } = countLowerCase   /* -- haskell equivalent   */
  .bind(n1 =&gt; countDigits      /* do n1 &lt;- countLowerCase */
    .bind(n2 =&gt; StateMonad     /*    n2 &lt;- countDigits    */
      .return_(n1 + n2)))      /*    return n1 + n2       */
  .runState("abc123ABC");
I'm probably off my rocker here, but what if rather than nested chains of bind, you used a fork/join type of approach?

static combine&lt;T, S, R&gt;(
    monads: { [P in keyof T]: StateMonad&lt;S, T[P]&gt; },
    selector: (values: T) =&gt; R
)
    : StateMonad&lt;S, R&gt; {
    return new StateMonad&lt;S, R&gt;((state) =&gt; {
    var ret: any = {};
    for (const key in monads) {
        if (monads.hasOwnProperty(key)) {
        ret[key] = monads[key].runState(state).a;
        }
    }
    return { a: selector(ret), s: state }
    }
    );
}


and

var { a } = StateMonad
  .combine(
    {
      countLowerCase,
      countDigits
    },
    combined =&gt;
      combined.countLowerCase +
      combined.countDigits
  )
  .runState("abc123ABC");