Closed safareli closed 8 years ago
We could get first Monad from generator to remove dependence on Free:
const step = (g) => (value) => {
const result = g.next(value)
return result.done
? result.value
: result.value.chain(step(g))
}
const runGenerator = (gen) => {
const firstM = step(gen())(undefined)
for (let key of Object.keys(firstM.constructor.prototype)){
firstM[key] = (...args) => {
const m = step(gen())(undefined);
return m[key](...args)
}
}
return firstM
}
const Monad = {
do: runGenerator
}
module.exports = Monad
Right on! Thanks for helping with this. I'm going to be spending some time on it over the weekend so I'll look it over for sure.
Welcome!
I really like that idea of using generators as haskell do like syntax and it will be nice if we could have it so that it is not tied to particular object and could be useful with anything that has chain.
But:
Monad.do(function* () {
let a = fib(100000000);
let b = yield Get('/fib='+a);
result Done(b + 1);
});
As we could not clone iterator it will not work for all monads :/ . I think if we use sweet.js to write a macro for do
will be nice
@safareli thanks for pointing this out. I was inspired by bodil's library https://github.com/bodil/eulalie/blob/master/src/index.js#L268 but I'd rather have uniformity and predictability rather than a fancy new syntax.
In my experience, I've found it way too easy to cheat this way and sneak in imperative one liners instead of something composable. I suppose we should axe it and stick with chain
Agreed, we should use chain Instead of generators.
I'll close this issue es there is no way to fix it.
As of in Fluture/issues/10 I'm reopening this issue.
Monad.do creates generator calles next on it and returns firs ocurance of Free monad. When we call foldMap on that it will drain generator as it should, but issue is that we could not reuse result of monad.do
For example if we dublicate example.js:41 it will fail, as both are useing one generator.
I have fixed this but not in the cleanest way here it is:
the key here is that instead of instantiating generator and getting first item from it we create Free like object which will create generators on each call so we could reuse that