<commit_before>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace ZedSharp
{
    public static class Maybe
    {
        public static Maybe<A> Of<A>(Nullable<A> nullable) where A : struct
        {
            return nullable.HasValue ? new Maybe<A>(nullable.Value) : new Maybe<A>();
        }

        public static Maybe<A> Of<A>(A val)
        {
            return new Maybe<A>(val);
        }

        public static Maybe<A> Some<A>(A val)
        {
            if (val == null)
                throw new ArgumentNullException("Can't create Maybe.Some<" + typeof(A) + "> with null value");

            return new Maybe<A>(val);
        }

        public static Maybe<A> None<A>()
        {
            return new Maybe<A>();
        }

        public static Maybe<A> Try<A>(Func<A> f)
        {
            try
            {
                return Of(f());
            }
            catch
            {
                return None<A>();
            }
        }

        public static Maybe<A> If<A>(A val, Func<A, bool> f)
        {
            return If(val, f, Z.Id);
        }

        public static Maybe<B> If<A, B>(A val, Func<A, bool> f, Func<A, B> convert)
        {
            return f(val) ? Of(convert(val)) : None<B>();
        }

        public static Lazy<Maybe<B>> LazyIf<A, B>(A val, Func<A, bool> f, Func<A, B> selector)
        {
            return new Lazy<Maybe<B>>(() => Maybe.If(val, f, selector));
        }

        public static Maybe<A> Flatten<A>(this Maybe<Maybe<A>> maybe)
        {
            return maybe.HasValue ? maybe.Value : None<A>();
        }

        public static Maybe<Int32> ToInt(this String s)
        {
            int i;
            return Int32.TryParse(s, out i) ? Maybe.Of(i) : Maybe.None<Int32>();
        }

        public static Maybe<Double> ToDouble(this String s)
        {
            double d;
            return Double.TryParse(s, out d) ? Maybe.Of(d) : Maybe.None<Double>();
        }

        public static Maybe<XDocument> ToXml(this String s)
        {
            return Try(() => XDocument.Parse(s));
        }

        public static Maybe<A> MaybeGet<A>(this IList<A> list, int index)
        {
            return Try(() => list[index]);
        }

        public static Maybe<B> MaybeGet<A, B>(this IDictionary<A, B> dict, A key)
        {
            return Try(() => dict[key]);
        }

        public static Maybe<A> MaybeFirst<A>(this IEnumerable<A> seq)
        {
            return Try(() => seq.First());
        }

        public static Maybe<A> MaybeLast<A>(this IEnumerable<A> seq)
        {
            return Try(() => seq.Last());
        }

        public static Maybe<A> MaybeSingle<A>(this IEnumerable<A> seq)
        {
            return Try(() => seq.Single());
        }

        public static Maybe<A> MaybeElementAt<A>(this IEnumerable<A> seq, int index)
        {
            return Try(() => seq.ElementAt(index));
        }

        public static IEnumerable<A> WhereSome<A>(this IEnumerable<Maybe<A>> seq)
        {
            foreach (var x in seq)
                if (x.HasValue)
                    yield return x.Value;
        }

        public static Maybe<IEnumerable<A>> Sequence<A>(this IEnumerable<Maybe<A>> seq)
        {
            var list = new List<A>();

            foreach (var x in seq)
                if (x.HasValue)
                    list.Add(x.Value);
                else
                    return Maybe.None<IEnumerable<A>>();

            return Maybe.Of(list).Cast<IEnumerable<A>>();
        }

        public static Func<A, Maybe<C>> Compose<A, B, C>(this Func<A, Maybe<B>> f, Func<B, Maybe<C>> g)
        {
            return a => f(a).SelectMany(g);
        }

        public static Maybe<IEnumerable<A>> NonEmpty<A>(Maybe<IEnumerable<A>> maybe)
        {
            return maybe.Where(Z.NonEmpty);
        }

        public static Maybe<List<A>> NonEmpty<A>(Maybe<List<A>> maybe)
        {
            return maybe.Where(Z.NonEmpty);
        }

        public static Maybe<String> NonEmpty(Maybe<String> maybe)
        {
            return maybe.Where(Z.NonEmpty);
        }

        public static Maybe<String> NonBlank(Maybe<String> maybe)
        {
            return maybe.Where(Z.NonBlank);
        }

        public static Maybe<int> NonNeg(Maybe<int> maybe)
        {
            return maybe.Where(Z.NonNeg);
        }

        public static Maybe<int> Pos(Maybe<int> maybe)
        {
            return maybe.Where(Z.Pos);
        }
    }
    
    /// <summary>
    /// A null-encapsulating wrapper.
    /// A Maybe might not have a value, not a reference to an Maybe can not be null.
    /// </summary>
    /// <typeparam name="A"></typeparam>
    public struct Maybe<A>
    {
        public static implicit operator Maybe<A>(A val)
        {
            return Maybe.Of(val);
        }

        public static bool operator true(Maybe<A> maybe)
        {
            return maybe.HasValue;
        }

        public static bool operator false(Maybe<A> maybe)
        {
            return ! maybe.HasValue;
        }

        internal Maybe(A val) : this()
        {
            Value = val;
            HasValue = val != null;
        }

        internal A Value { get; set; }
        public bool HasValue { get; private set; }

        public Type InnerType { get { return typeof(A); } }

        public Maybe<B> Select<B>(Func<A, B> f)
        {
            var val = Value;
            return HasValue ? Maybe.Try(() => f(val)) : Maybe.None<B>();
        }

        public Maybe<B> SelectMany<B>(Func<A, Maybe<B>> f)
        {
            return Select(f).Flatten();
        }

        public Maybe<A> Where(Func<A, bool> f)
        {<commit_msg>Added | and & operators for Maybe<commit_after>﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;

namespace ZedSharp
{
    public static class Maybe
    {
        public static Maybe<A> Of<A>(Nullable<A> nullable) where A : struct
        {
            return nullable.HasValue ? new Maybe<A>(nullable.Value) : new Maybe<A>();
        }

        public static Maybe<A> Of<A>(A val)
        {
            return new Maybe<A>(val);
        }

        public static Maybe<A> Some<A>(A val)
        {
            if (val == null)
                throw new ArgumentNullException("Can't create Maybe.Some<" + typeof(A) + "> with null value");

            return new Maybe<A>(val);
        }

        public static Maybe<A> None<A>()
        {
            return new Maybe<A>();
        }

        public static Maybe<A> Try<A>(Func<A> f)
        {
            try
            {
                return Of(f());
            }
            catch
            {
                return None<A>();
            }
        }

        public static Maybe<A> If<A>(A val, Func<A, bool> f)
        {
            return If(val, f, Z.Id);
        }

        public static Maybe<B> If<A, B>(A val, Func<A, bool> f, Func<A, B> convert)
        {
            return f(val) ? Of(convert(val)) : None<B>();
        }

        public static Lazy<Maybe<B>> LazyIf<A, B>(A val, Func<A, bool> f, Func<A, B> selector)
        {
            return new Lazy<Maybe<B>>(() => Maybe.If(val, f, selector));
        }

        public static Maybe<A> Flatten<A>(this Maybe<Maybe<A>> maybe)
        {
            return maybe.HasValue ? maybe.Value : None<A>();
        }

        public static Maybe<Int32> ToInt(this String s)
        {
            int i;
            return Int32.TryParse(s, out i) ? Maybe.Of(i) : Maybe.None<Int32>();
        }

        public static Maybe<Double> ToDouble(this String s)
        {
            double d;
            return Double.TryParse(s, out d) ? Maybe.Of(d) : Maybe.None<Double>();
        }

        public static Maybe<XDocument> ToXml(this String s)
        {
            return Try(() => XDocument.Parse(s));
        }

        public static Maybe<A> MaybeGet<A>(this IList<A> list, int index)
        {
            return Try(() => list[index]);
        }

        public static Maybe<B> MaybeGet<A, B>(this IDictionary<A, B> dict, A key)
        {
            return Try(() => dict[key]);
        }

        public static Maybe<A> MaybeFirst<A>(this IEnumerable<A> seq)
        {
            return Try(() => seq.First());
        }

        public static Maybe<A> MaybeLast<A>(this IEnumerable<A> seq)
        {
            return Try(() => seq.Last());
        }

        public static Maybe<A> MaybeSingle<A>(this IEnumerable<A> seq)
        {
            return Try(() => seq.Single());
        }

        public static Maybe<A> MaybeElementAt<A>(this IEnumerable<A> seq, int index)
        {
            return Try(() => seq.ElementAt(index));
        }

        public static IEnumerable<A> WhereSome<A>(this IEnumerable<Maybe<A>> seq)
        {
            foreach (var x in seq)
                if (x.HasValue)
                    yield return x.Value;
        }

        public static Maybe<IEnumerable<A>> Sequence<A>(this IEnumerable<Maybe<A>> seq)
        {
            var list = new List<A>();

            foreach (var x in seq)
                if (x.HasValue)
                    list.Add(x.Value);
                else
                    return Maybe.None<IEnumerable<A>>();

            return Maybe.Of(list).Cast<IEnumerable<A>>();
        }

        public static Func<A, Maybe<C>> Compose<A, B, C>(this Func<A, Maybe<B>> f, Func<B, Maybe<C>> g)
        {
            return a => f(a).SelectMany(g);
        }

        public static Maybe<IEnumerable<A>> NonEmpty<A>(Maybe<IEnumerable<A>> maybe)
        {
            return maybe.Where(Z.NonEmpty);
        }

        public static Maybe<List<A>> NonEmpty<A>(Maybe<List<A>> maybe)
        {
            return maybe.Where(Z.NonEmpty);
        }

        public static Maybe<String> NonEmpty(Maybe<String> maybe)
        {
            return maybe.Where(Z.NonEmpty);
        }

        public static Maybe<String> NonBlank(Maybe<String> maybe)
        {
            return maybe.Where(Z.NonBlank);
        }

        public static Maybe<int> NonNeg(Maybe<int> maybe)
        {
            return maybe.Where(Z.NonNeg);
        }

        public static Maybe<int> Pos(Maybe<int> maybe)
        {
            return maybe.Where(Z.Pos);
        }
    }
    
    /// <summary>
    /// A null-encapsulating wrapper.
    /// A Maybe might not have a value, but a reference to an Maybe will not itself be null.
    /// </summary>
    /// <typeparam name="A"></typeparam>
    public struct Maybe<A>
    {
        public static implicit operator Maybe<A>(A val)
        {
            return Maybe.Of(val);
        }

        public static bool operator true(Maybe<A> maybe)
        {
            return maybe.HasValue;
        }

        public static bool operator false(Maybe<A> maybe)
        {
            return ! maybe.HasValue;
        }

        public static Maybe<A> operator |(Maybe<A> lhs, Maybe<A> rhs)
        {
            return lhs.Or(rhs);
        }

        public static Maybe<A> operator &(Maybe<A> lhs, Maybe<A> rhs)
        {
            return (lhs.HasValue && rhs.HasValue) ? lhs : Maybe.None<A>();
        }

        internal Maybe(A val) : this()
        {
            Value = val;
            HasValue = val != null;
        }

        internal A Value { get; set; }
        public bool HasValue { get; private set; }

        public Type InnerType { get { return typeof(A); } }

        public Maybe<B> Select<B>(Func<A, B> f)
        {
            var val = Value;
            return HasValue ? Maybe.Try(() => f(val)) : Maybe.None<B>();
        }

        public Maybe<B> SelectMany<B>(Func<A, Maybe<B>> f)
        {
            return Select(f).Flatten();
        }

        public Maybe<A> Where(Func<A, bool> f)
        {
{'fraction_non_alphanumeric': 0.12998222899213, 'fraction_numerical': 0.0010154861640010156, 'mean_word_length': 1.5826048951048952, 'pattern_counts': {'":': 0, '<': 248, '<?xml version=': 0, '>': 268, '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': '2800281', 'n_tokens_mistral': 3558, 'n_tokens_neox': 3453, 'n_words': 884}