seance / do-m

Monadic do-comprehension like syntax for JavaScript using generators

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

doM

Monadic do-comprehension like syntax for JavaScript using generators

Reference

doM(comprehension: function*, reentrant?: boolean)

Do-syntax for comprehension's algebraic type. If reentrant is true, uses a re-entry safe version — it's up to the user to signal when this is necessary.

Re-entrancy is necessary for Lists and other multi-valued types, where the function argument generated by doM for chain could be called multiple times.

doM is syntactic sugaring for nested chain calls:

// doM syntactic sugaring, single level of nesting
doM(function*() {
    const v1 = yield expression1(...)
    ...
    const vN = yield expressionN(...)
    return expression(v1, vN)
})

// Corresponding nested chain expressions, N+1 levels of nesting
expression1(...).chain(v1 =>
    ...
        expressionN(...).chain(vN =>
            expression(v1, vN)))

Example

For some hypothetical types List and Option (that conform to the Fantasy Land Specification), you could write for example the following comprehensions:

const res1 = doM(function*() {
    const x = yield List.fromArray([1, 2])
    const y = yield List.fromArray([3, 4])
    return List.fromArray([x + y])
}, true)

console.log(res1) //=> List { xs: [ 4, 5, 5, 6 ] }

const res2 = doM(function*() {
    const x = yield Option.some(1)
    const y = yield Option.some(2)
    return Option.some(x + y)
})

console.log(res2) //=> Some { x: 3 }

const res3 = function() {
    const xs = List.fromArray([...Array(2).keys()])
    const ys = List.fromArray([...Array(2).keys()])

    return doM(function*() {
        const x = yield xs.chain(x => List.fromArray([x, x + 1]))
        const y = yield ys.map(y => y + 1)
        return List.fromArray([x * y])
    }, true)
}()

console.log(res3) //=> List { xs: [ 0, 0, 1, 2, 1, 2, 2, 4 ] }

About

Monadic do-comprehension like syntax for JavaScript using generators


Languages

Language:JavaScript 100.0%