Skip to content

Instantly share code, notes, and snippets.

@nameoverflow nameoverflow/doM.ts
Last active Dec 23, 2018

Embed
What would you like to do?
Monad-like do-notation in TypeScript
export interface Monad<T> {
mbind<U>(t: (T) => Monad<U>): Monad<U>
mreturn<U>(v: U): Monad<U>
}
abstract class Maybe<T> implements Monad<T> {
abstract mbind<U>(t: (T) => Maybe<U>): Maybe<U>
mreturn<U>(v: U): Maybe<U> {
return new Just(v)
}
}
class Just<T> extends Maybe<T> {
private value: T
constructor(v: T) {
super()
this.value = v
}
mbind<U>(t: (T) => Maybe<U>): Maybe<U> {
return t(this.value)
}
}
class Nothing<T> extends Maybe<T> {
mbind<U>(t: (T) => Maybe<U>): Maybe<U> {
return this
}
}
export default function doM<T>(g: () => IterableIterator<Monad<T>>): Monad<T> {
let m = g()
const run = (v) => {
const res = m.next(v)
if (res.done) {
return res.value
}
return res.value.mbind(run)
}
return run(undefined)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.