<commit_before>﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace LanguageExt.TypeClasses
{
    ///// <summary>
    ///// Monad type-class
    ///// </summary>
    ///// <typeparam name="A">Bound value</typeparam>
    //[Typeclass]
    public interface Monad<MA, A> : Monad<Unit, Unit, MA, A>, Foldable<MA, A>
    {
        MA Return(A x);
    }

    /// <summary>
    /// Monad type-class
    /// </summary>
    /// <typeparam name="A">Bound value</typeparam>
    [Typeclass]
    public interface Monad<Env, Out, MA, A> : Foldable<Env, MA, A>
    {
        /// <summary>
        /// Monadic bind
        /// </summary>
        /// <typeparam name="MONADB">Type-class of the return value</typeparam>
        /// <typeparam name="MB">Type of the monad to return</typeparam>
        /// <typeparam name="B">Type of the bound return value</typeparam>
        /// <param name="ma">Monad to bind</param>
        /// <param name="f">Bind function</param>
        /// <returns>Monad of type MB derived from Monad of B</returns>
        [Pure]
        MB Bind<MONADB, MB, B>(MA ma, Func<A, MB> f) 
            where MONADB : struct, Monad<Env, Out, MB, B>;

        ///// <summary>
        ///// Monad return
        ///// </summary>
        ///// <typeparam name="A">Type of the bound monad value</typeparam>
        ///// <param name="x">The bound monad value</param>
        ///// <returns>Monad of A</returns>
        //[Pure]
        //MA Return(A x);

        MA Return(Func<Env, A> f);
        MA Id(Func<Env, MA> ma);

        MA BindOutput(Out maOutput, MA mb);

        ///// <summary>
        ///// Monad return
        ///// </summary>
        ///// <param name="f">The function to invoke to get the bound monad value(s)</param>
        ///// <returns>Monad of A</returns>
        //[Pure]
        //MA Return(Func<Env, (A, Env, bool)> f);

        ///// <summary>
        ///// Monad run
        ///// </summary>
        ///// <param name="f">The function to invoke to get the monad value(s)</param>
        ///// <returns>Monad of A</returns>
        //[Pure]
        //(A, Env, bool) Eval(MA ma, Env e);

        /// <summary>
        /// Produce a failure value
        /// </summary>
        [Pure]
        MA Fail(Exception err = null);

        /// <summary>
        /// Produce a failure value
        /// </summary>
        [Pure]
        MA Fail(object err);

        /// <summary><commit_msg>Tidying the Monad type<commit_after>﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace LanguageExt.TypeClasses
{
    ///// <summary>
    ///// Monad type-class
    ///// </summary>
    /// <typeparam name="MA">The data-type to make monadic</typeparam>
    /// <typeparam name="A">The data-type bound value</typeparam>
    [Typeclass]
    public interface Monad<MA, A> : Monad<Unit, Unit, MA, A>, Foldable<MA, A>
    {
        MA Return(A x);
    }

    /// <summary>
    /// Monad type-class
    /// </summary>
    /// <typeparam name="Env">The input type to the monadic computation</typeparam>
    /// <typeparam name="Out">The output type of the monadic computation</typeparam>
    /// <typeparam name="MA">The data-type to make monadic</typeparam>
    /// <typeparam name="A">The data-type bound value</typeparam>
    [Typeclass]
    public interface Monad<Env, Out, MA, A> : Foldable<Env, MA, A>
    {
        /// <summary>
        /// Monadic bind
        /// </summary>
        /// <typeparam name="MONADB">Type-class of the return value</typeparam>
        /// <typeparam name="MB">Type of the monad to return</typeparam>
        /// <typeparam name="B">Type of the bound return value</typeparam>
        /// <param name="ma">Monad to bind</param>
        /// <param name="f">Bind function</param>
        /// <returns>Monad of type MB derived from Monad of B</returns>
        [Pure]
        MB Bind<MONADB, MB, B>(MA ma, Func<A, MB> f) 
            where MONADB : struct, Monad<Env, Out, MB, B>;

        /// <summary>
        /// Lazy monad construction
        /// </summary>
        MA Return(Func<Env, A> f);

        /// <summary>
        /// Monad identity
        /// </summary>
        MA Id(Func<Env, MA> ma);

        /// <summary>
        /// Used for double dispatch by the bind function for monadic types that
        /// need to construct an output value/state (like MState and MWriter).  For
        /// all other monad types just return mb.
        /// </summary>
        /// <param name="maOutput">Output from the first part of a monadic bind</param>
        /// <param name="mb">Monadic to invoke.  Get the results from this to combine with
        /// maOutput and then re-wrap</param>
        /// <returns>Monad with the combined output</returns>
        MA BindOutput(Out maOutput, MA mb);

        /// <summary>
        /// Produce a failure value
        /// </summary>
        [Pure]
        MA Fail(Exception err = null);

        /// <summary>
        /// Produce a failure value
        /// </summary>
        [Pure]
        MA Fail(object err);

        /// <summary>
{'fraction_non_alphanumeric': 0.16643795334248188, 'fraction_numerical': 0.0, 'mean_word_length': 1.7940854326396496, 'pattern_counts': {'":': 0, '<': 118, '<?xml version=': 0, '>': 118, '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': '3620006', 'n_tokens_mistral': 1567, 'n_tokens_neox': 1541, 'n_words': 453}