<commit_before>/*
 * loquat-monad / monad.js
 * copyright (c) 2016 Susisu
 */

/**
 * @module monad
 */

"use strict";

module.exports = _core => {
    function end() {
        return Object.freeze({
            forever,
            voidM,
            join,
            when,
            unless,
            liftM,
            liftM2,
            liftM3,
            liftM4,
            liftM5,
            ltor,
            rtol,
            sequence,
            sequence_,
            mapM,
            mapM_,
            forM,
            forM_,
            filterM,
            zipWithM,
            zipWithM_,
            foldM,
            foldM_,
            replicateM,
            replicateM_,
            guard,
            _internal: {
                zipWith
            }
        });
    }

    const ParseError = _core.ParseError;
    const Result     = _core.Result;
    const Parser     = _core.Parser;
    const lazy       = _core.lazy;

    const _prim = require("loquat-prim")(_core);
    const map   = _prim.map;
    const pure  = _prim.pure;
    const bind  = _prim.bind;
    const then  = _prim.then;
    const mzero = _prim.mzero;

    /**
     * @function module:monad.forever
     * @static
     * @param {AbstractParser} parser
     * @returns {AbstractParser}
     */
    function forever(parser) {
        const rec = lazy(() => then(parser, rec));
        return rec;
    }

    /**
     * @function module:monad.voidM
     * @static
     * @param {AbstractParser} parser
     * @returns {AbstractParser}
     */
    function voidM(parser) {
        return map(parser, () => undefined);
    }

    /**
     * @function module:monad.join
     * @static
     * @param {AbstractParser} parser
     * @returns {AbstractParser}
     */
    function join(parser) {
        return bind(parser, val => val);
    }

    /**
     * @function module:monad.when
     * @static
     * @param {boolean} flag
     * @param {AbstractParser} parser
     * @returns {AbstractParser}
     */
    function when(flag, parser) {
        return flag ? parser : pure(undefined);
    }

    /**
     * @function module:monad.unless
     * @static
     * @param {boolean} flag
     * @param {AbstractParser} parser
     * @returns {AbstractParser}
     */
    function unless(flag, parser) {
        return flag ? pure(undefined) : parser;
    }

    /**
     * @function module:monad.liftM
     * @static
     * @param {function} func
     * @returns {function}
     */
    function liftM(func) {
        return parser => bind(parser, val => pure(func(val)));
    }

    /**
     * @function module:monad.liftM2
     * @static
     * @param {function} func
     * @returns {function}
     */
    function liftM2(func) {
        return (parserA, parserB) =>
            bind(parserA, valA =>
                bind(parserB, valB =>
                    pure(func(valA, valB))
                )
            );
    }

    /**
     * @function module:monad.liftM3
     * @static<commit_msg>[monad] Rename parameters<commit_after>/*
 * loquat-monad / monad.js
 * copyright (c) 2016 Susisu
 */

/**
 * @module monad
 */

"use strict";

module.exports = _core => {
    function end() {
        return Object.freeze({
            forever,
            voidM,
            join,
            when,
            unless,
            liftM,
            liftM2,
            liftM3,
            liftM4,
            liftM5,
            ltor,
            rtol,
            sequence,
            sequence_,
            mapM,
            mapM_,
            forM,
            forM_,
            filterM,
            zipWithM,
            zipWithM_,
            foldM,
            foldM_,
            replicateM,
            replicateM_,
            guard,
            _internal: {
                zipWith
            }
        });
    }

    const ParseError = _core.ParseError;
    const Result     = _core.Result;
    const Parser     = _core.Parser;
    const lazy       = _core.lazy;

    const _prim = require("loquat-prim")(_core);
    const map   = _prim.map;
    const pure  = _prim.pure;
    const bind  = _prim.bind;
    const then  = _prim.then;
    const mzero = _prim.mzero;

    /**
     * @function module:monad.forever
     * @static
     * @param {AbstractParser} parser
     * @returns {AbstractParser}
     */
    function forever(parser) {
        const rec = lazy(() => then(parser, rec));
        return rec;
    }

    /**
     * @function module:monad.voidM
     * @static
     * @param {AbstractParser} parser
     * @returns {AbstractParser}
     */
    function voidM(parser) {
        return map(parser, () => undefined);
    }

    /**
     * @function module:monad.join
     * @static
     * @param {AbstractParser} parser
     * @returns {AbstractParser}
     */
    function join(parser) {
        return bind(parser, val => val);
    }

    /**
     * @function module:monad.when
     * @static
     * @param {boolean} cond
     * @param {AbstractParser} parser
     * @returns {AbstractParser}
     */
    function when(cond, parser) {
        return cond ? parser : pure(undefined);
    }

    /**
     * @function module:monad.unless
     * @static
     * @param {boolean} cond
     * @param {AbstractParser} parser
     * @returns {AbstractParser}
     */
    function unless(cond, parser) {
        return cond ? pure(undefined) : parser;
    }

    /**
     * @function module:monad.liftM
     * @static
     * @param {function} func
     * @returns {function}
     */
    function liftM(func) {
        return parser => bind(parser, val => pure(func(val)));
    }

    /**
     * @function module:monad.liftM2
     * @static
     * @param {function} func
     * @returns {function}
     */
    function liftM2(func) {
        return (parserA, parserB) =>
            bind(parserA, valA =>
                bind(parserB, valB =>
                    pure(func(valA, valB))
                )
            );
    }

    /**
     * @function module:monad.liftM3
     * @static
{'fraction_non_alphanumeric': 0.11823647294589178, 'fraction_numerical': 0.003674014696058784, 'mean_word_length': 1.4696907216494846, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1766414', 'n_tokens_mistral': 1827, 'n_tokens_neox': 1781, 'n_words': 385}