Skip to content

Instantly share code, notes, and snippets.

@raveclassic
Created October 22, 2017 07:52
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raveclassic/f7df7276467d6fcd548248b53d585b4b to your computer and use it in GitHub Desktop.
Save raveclassic/f7df7276467d6fcd548248b53d585b4b to your computer and use it in GitHub Desktop.
import { right, either, left } from 'fp-ts/lib/Either'
import { HKTAs, HKT2As, HKT2, HKTS, HKT, HKT2S } from 'fp-ts/lib/HKT'
import { Monad } from 'fp-ts/lib/Monad'
import { option, some } from 'fp-ts/lib/Option'
function Do<M extends HKT2S>(m: Monad<M>): <L, A>(generator: () => Iterator<HKT2<M, L, A>>) => HKT2As<M, L, A>
function Do<M extends HKTS>(m: Monad<M>): <A>(generator: () => Iterator<HKT<M, A>>) => HKTAs<M, A>
function Do<M extends HKTS>(m: Monad<M>): <A>(generator: () => Iterator<HKT<M, A>>) => HKT<M, A> {
return <A>(generator: () => Iterator<HKT<M, A>>): HKT<M, A> => {
const iterator = generator()
const state = iterator.next()
const run = (state: IteratorResult<HKT<M, A>>): HKT<M, A> => {
if (state.done) {
// any - if iterator is done, then its type is A, not HKT<M, A>
return m.of(state.value as any)
}
return m.chain(value => run(iterator.next(value)), state.value)
}
return run(state)
}
}
const res1 = Do(option)(function*() {
const one = yield some(1)
const two = 2
const three = yield some(3)
return one + two + three
})
const res2 = Do(either)(function*() {
const one = yield right(1)
const two = 2
const three = yield left('Failure!')
return one + two + three
})
console.log(res1) // some(6)
console.log(res2) // left("Failure!")
@patroza
Copy link

patroza commented May 22, 2020

@raveclassic - im loving this, is there any update now that

@raveclassic
Copy link
Author

@patroza Thanks!

Unfortunately, the changes made to type checking generators in TS are not enough. They still don't allow higher-order yield/next types.

@nythrox
Copy link

nythrox commented Aug 30, 2020

@patroza @raveclassic I believe it's possible with typescript's current support, see
gcanti/fp-ts#261 (comment)
gcanti/fp-ts#261 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment