the computation expression is "doing something behind the scenes" between each expression.
from Computation expressions: Introduction
今までで一番わかりやすい説明
First-class coroutines, represented as objects encapsulating suspended execution contexts (i.e., function activations). Prior art: Python, Icon, Lua, Scheme, Smalltalk.
function *generatorFunction() {
var a = yield 1; console.log(a); // x var b = yield 2; console.log(b); // y return 3; } var generator = generatorFunction(); var ret = generator.next(); console.log(ret.value); // 1 ret = generator.next('x'); console.log(ret.value); // 2 ret = generator.next('y'); console.log(ret.value); // 3
"doing something in behind the scenes"
between each expression
var mflow = require('mflow');
var maybe = mflow.maybe;
function add(x, y) {
return maybe(function *() {
var a = yield x;
var b = yield y;
return a + b;
});
}
console.log(add(1, 2)()); // 3
console.log(add(1, null)()); // null
open FSharpx open FSharpx.Option let add x y = maybe { let! a = x let! b = y return a + b} [<EntryPoint>] let main argv = printfn "%A" (add (Some 1) (Some 2)) // Some(3) printfn "%A" (add (Some 1) None) // <null> 0
function add(x, y) {
return maybe(function *() { var a = yield x; var b = yield y; return a + b; }); }
let add x y = maybe { let! a = x let! b = y return a + b}
var lazy= require('mflow').lazy; var x = 10; var lazyValue1 = lazy(function *() { return x + 10; }); var lazyValue2 = lazy(function *() { return x * 10; }); function add(value1, value2) { return lazy(function *() { return (yield value1) + (yield value2);
}); }; console.log(add(lazyValue1, lazyValue2)); // 120 console.log(add(1, 2)); // 3
type State<'T, 'State> = 'State -> 'T * 'State type Writer<'W, 'T> = unit -> 'T * 'W type Reader<'R,'T> = 'R -> 'T
Mflowには含めなかったが、WriterもReaderもJSで実現できた
var state = require('mflow').state;
function pop() { return function (s) { return [s.shift(), s]; }; } var flow = state(function* () { return yield pop(); });
var result = flow([9, 0, 2, 1, 0]);
console.log(result); // [9, [0, 2, 1, 0]]