generators are dashed jolly spiffy
@bodil
Write a filter function!
&filter(i => i > 2, take(6, infinity)); // 3 ⇨ 4 ⇨ 5
Write the filter function using generators!
&filter(i => i > 2, take(6, infinity())); // 3 ⇨ 4 ⇨ 5
Make run handle errors!
&run(fetchText("http://horse.ebooks/")); // TypeError: Failed to fetch Hint: Promise.then(successFn, errorFn) Deferred.reject(error)
Make maybe report errors!
&run(pie()); // "Rainbow Dash is friends with Pinkie Pie" &run(twi()); // Error: undefined key: twi
interface Async<A> { then: (f: (a: A) => Async<B>) => Async<B>; }
interface Async<A> { unit: (value: A) => Async<A>; then: (f: (a: A) => Async<B>) => Async<B>; }
then
.then
chains go away using yield
.We can do this with anything which has a then
method, not just promises!
run(function*() { const a = yield fs.readFile("a.txt"); const b = yield fs.readFile("b.txt"); yield fs.writeFile("both.txt", a + b); });
main = do a <- readFile "a.txt" b <- readFile "b.txt" writeFile "both.txt" (a ++ b)
function joinFiles(f1, f2, f3, callback) { fs.readFile(f1, function(err, a) { if (err) return callback(err); fs.readFile(f2, function(err, b) { if (err) return callback(err); fs.writeFile(f3, a + b, callback); }); }); }
until one man proposed a solution
MONADS
class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b
interface Monad<A> { unit: (value: A) => Monad<A>; then: (f: (a: A) => Monad<B>) => Monad<B>; }
Promise
)main = do a <- readFile "a.txt" b <- readFile "b.txt" writeFile "both.txt" (a ++ b)
run(function*() { const a = yield fs.readFile("a.txt"); const b = yield fs.readFile("b.txt"); yield fs.writeFile("both.txt", a + b); });
// §1. Left identity: unit(a).then(f) ≡ unit(f(a)); // §2. Right identity: m.then(unit) ≡ m; // §3. Associativity: m.then(f).then(g) ≡ m.then(a => g(f(a)));
https://github.com/tj/co
that is all
@bodil — http://bodil.lol/generators/