<commit_before>﻿using System;
using System.Linq;
using System.Collections.Generic;
using static LanguageExt.TypeClass;
using static LanguageExt.Prelude;
using System.Diagnostics.Contracts;
using LanguageExt.ClassInstances;
using System.Threading.Tasks;

namespace LanguageExt
{
    /// <summary>
    /// Discriminated union type.  Can be in one of two states:
    /// 
    ///     Some(a)
    ///     None
    ///     
    /// Typeclass instances available for this type:
    /// 
    ///     Applicative   : ApplOptionAsync
    ///     BiFoldable    : MOptionAsync
    ///     Foldable      : MOptionAsync
    ///     Functor       : FOptionAsync
    ///     Monad         : MOptionAsync
    ///     OptionalAsync : MOptionAsync
    ///     
    /// </summary>
    /// <typeparam name="A">Bound value</typeparam>
    public struct OptionAsync<A> :
        IOptionalAsync
    {
        internal readonly Task<OptionData<A>> data;

        /// <summary>
        /// None
        /// </summary>
        public static readonly OptionAsync<A> None = new OptionAsync<A>(OptionData<A>.None.AsTask());

        /// <summary>
        /// Construct an OptionAsync of A in a Some state
        /// </summary>
        /// <param name="value">Value to bind, must be non-null</param>
        /// <returns>OptionAsync of A</returns>
        [Pure]
        public static OptionAsync<A> Some(A value) =>
            new OptionAsync<A>(OptionData<A>.Some(value).AsTask());

        /// <summary>
        /// Construct an OptionAsync of A in a Some state
        /// </summary>
        /// <param name="value">Value to bind, must be non-null</param>
        /// <returns>OptionAsync of A</returns>
        [Pure]
        public static OptionAsync<A> SomeAsync(Task<A> value) =>
            new OptionAsync<A>(value.Map(a => OptionData<A>.Some(a)));

        /// <summary>
        /// Construct an OptionAsync of A in a Some state
        /// </summary>
        /// <param name="value">Value to bind, must be non-null</param>
        /// <returns>OptionAsync of A</returns>
        [Pure]
        public static OptionAsync<A> Optional(A value) =>
            new OptionAsync<A>(OptionData<A>.Optional(value).AsTask());

        /// <summary>
        /// Construct an OptionAsync of A in a Some state
        /// </summary>
        /// <param name="value">Value to bind, must be non-null</param>
        /// <returns>OptionAsync of A</returns>
        [Pure]
        public static OptionAsync<A> OptionalAsync(Task<A> value) =>
            new OptionAsync<A>(value.Map(a => OptionData<A>.Optional(a)));

        /// <summary>
        /// Takes the value-type OptionV<A>
        /// </summary>
        internal OptionAsync(Task<OptionData<A>> data) =>
            this.data = data;

        /// <summary>
        /// Ctor that facilitates serialisation
        /// </summary>
        /// <param name="option">None or Some A.</param>
        [Pure]
        public OptionAsync(IEnumerable<A> option)
        {
            var first = option.Take(1).ToArray();
            this.data = first.Length == 0
                ? OptionData<A>.None.AsTask()
                : OptionData<A>.Optional(first[0]).AsTask();
        }

        /// <summary>
        /// Implicit conversion operator from A to Option<A>
        /// </summary>
        /// <param name="a">Unit value</param>
        [Pure]
        public static implicit operator OptionAsync<A>(A a) =>
            OptionalAsync(a.AsTask());

        /// <summary>
        /// Implicit conversion operator from A to Option<A>
        /// </summary>
        /// <param name="a">Unit value</param>
        [Pure]
        public static implicit operator OptionAsync<A>(Task<A> a) =>
            OptionalAsync(a);

        /// Implicit conversion operator from None to Option<A>
        /// </summary>
        /// <param name="a">None value</param>
        [Pure]
        public static implicit operator OptionAsync<A>(OptionNone a) =>
            None;

        /// <summary>
        /// Coalescing operator
        /// </summary>
        /// <param name="lhs">Left hand side of the operation</param>
        /// <param name="rhs">Right hand side of the operation</param>
        /// <returns>if lhs is Some then lhs, else rhs</returns>
        [Pure]
        public static OptionAsync<A> operator |(OptionAsync<A> lhs, OptionAsync<A> rhs) =>
            MOptionAsync<A>.Inst.Plus(lhs, rhs);

        /// <summary>
        /// Calculate the hash-code from the bound value, unless the Option is in a None
        /// state, in which case the hash-code will be 0
        /// </summary>
        /// <returns>Hash-code from the bound value, unless the Option is in a None
        /// state, in which case the hash-code will be 0</returns>
        [Pure]
        public override int GetHashCode() =>
            IsSome.Result
                ? Value.GetHashCode()
                : 0;

        /// <summary>
        /// Calculate the hash-code from the bound value, unless the Option is in a None
        /// state, in which case the hash-code will be 0
        /// </summary>
        /// <returns>Hash-code from the bound value, unless the Option is in a None
        /// state, in which case the hash-code will be 0</returns>
        [Pure]
        public Task<int> GetHashCodeAsync() =>
            data.Map(a => a.GetHashCode());

        /// <summary>
        /// Get a string representation of the Option
        /// </summary>
        /// <returns>String representation of the Option</returns>
        [Pure]
        public override string ToString() =>
            IsSome.Result
                ? $"Some({Value.Result})"
                : "None";

        /// <summary>
        /// Get a string representation of the Option
        /// </summary>
        /// <returns>String representation of the Option</returns>
        [Pure]
        public Task<string> ToStringAsync() =>
            data.Map(toString);

        /// <summary>
        /// Is the option in a Some state
        /// </summary>
        [Pure]
        public Task<bool> IsSome =>
            data.Map(a => a.IsSome);

        /// <summary>
        /// Is the option in a None state
        /// </summary>
        [Pure]
        public Task<bool> IsNone =>
            data.Map(a => a.IsNone);

        /// <summary>
        /// Helper accessor for the bound value
        /// </summary>
        internal Task<A> Value =>
            data.Map(a => a.Value);
<commit_msg>defined ToString and GetHashCode on OptionAsync using their async counterparts<commit_after>﻿using System;
using System.Linq;
using System.Collections.Generic;
using static LanguageExt.TypeClass;
using static LanguageExt.Prelude;
using System.Diagnostics.Contracts;
using LanguageExt.ClassInstances;
using System.Threading.Tasks;

namespace LanguageExt
{
    /// <summary>
    /// Discriminated union type.  Can be in one of two states:
    /// 
    ///     Some(a)
    ///     None
    ///     
    /// Typeclass instances available for this type:
    /// 
    ///     Applicative   : ApplOptionAsync
    ///     BiFoldable    : MOptionAsync
    ///     Foldable      : MOptionAsync
    ///     Functor       : FOptionAsync
    ///     Monad         : MOptionAsync
    ///     OptionalAsync : MOptionAsync
    ///     
    /// </summary>
    /// <typeparam name="A">Bound value</typeparam>
    public struct OptionAsync<A> :
        IOptionalAsync
    {
        internal readonly Task<OptionData<A>> data;

        /// <summary>
        /// None
        /// </summary>
        public static readonly OptionAsync<A> None = new OptionAsync<A>(OptionData<A>.None.AsTask());

        /// <summary>
        /// Construct an OptionAsync of A in a Some state
        /// </summary>
        /// <param name="value">Value to bind, must be non-null</param>
        /// <returns>OptionAsync of A</returns>
        [Pure]
        public static OptionAsync<A> Some(A value) =>
            new OptionAsync<A>(OptionData<A>.Some(value).AsTask());

        /// <summary>
        /// Construct an OptionAsync of A in a Some state
        /// </summary>
        /// <param name="value">Value to bind, must be non-null</param>
        /// <returns>OptionAsync of A</returns>
        [Pure]
        public static OptionAsync<A> SomeAsync(Task<A> value) =>
            new OptionAsync<A>(value.Map(a => OptionData<A>.Some(a)));

        /// <summary>
        /// Construct an OptionAsync of A in a Some state
        /// </summary>
        /// <param name="value">Value to bind, must be non-null</param>
        /// <returns>OptionAsync of A</returns>
        [Pure]
        public static OptionAsync<A> Optional(A value) =>
            new OptionAsync<A>(OptionData<A>.Optional(value).AsTask());

        /// <summary>
        /// Construct an OptionAsync of A in a Some state
        /// </summary>
        /// <param name="value">Value to bind, must be non-null</param>
        /// <returns>OptionAsync of A</returns>
        [Pure]
        public static OptionAsync<A> OptionalAsync(Task<A> value) =>
            new OptionAsync<A>(value.Map(a => OptionData<A>.Optional(a)));

        /// <summary>
        /// Takes the value-type OptionV<A>
        /// </summary>
        internal OptionAsync(Task<OptionData<A>> data) =>
            this.data = data;

        /// <summary>
        /// Ctor that facilitates serialisation
        /// </summary>
        /// <param name="option">None or Some A.</param>
        [Pure]
        public OptionAsync(IEnumerable<A> option)
        {
            var first = option.Take(1).ToArray();
            this.data = first.Length == 0
                ? OptionData<A>.None.AsTask()
                : OptionData<A>.Optional(first[0]).AsTask();
        }

        /// <summary>
        /// Implicit conversion operator from A to Option<A>
        /// </summary>
        /// <param name="a">Unit value</param>
        [Pure]
        public static implicit operator OptionAsync<A>(A a) =>
            OptionalAsync(a.AsTask());

        /// <summary>
        /// Implicit conversion operator from A to Option<A>
        /// </summary>
        /// <param name="a">Unit value</param>
        [Pure]
        public static implicit operator OptionAsync<A>(Task<A> a) =>
            OptionalAsync(a);

        /// Implicit conversion operator from None to Option<A>
        /// </summary>
        /// <param name="a">None value</param>
        [Pure]
        public static implicit operator OptionAsync<A>(OptionNone a) =>
            None;

        /// <summary>
        /// Coalescing operator
        /// </summary>
        /// <param name="lhs">Left hand side of the operation</param>
        /// <param name="rhs">Right hand side of the operation</param>
        /// <returns>if lhs is Some then lhs, else rhs</returns>
        [Pure]
        public static OptionAsync<A> operator |(OptionAsync<A> lhs, OptionAsync<A> rhs) =>
            MOptionAsync<A>.Inst.Plus(lhs, rhs);

        /// <summary>
        /// Calculate the hash-code from the bound value, unless the Option is in a None
        /// state, in which case the hash-code will be 0
        /// </summary>
        /// <returns>Hash-code from the bound value, unless the Option is in a None
        /// state, in which case the hash-code will be 0</returns>
        [Pure]
        public override int GetHashCode() =>
            GetHashCodeAsync().Result;

        /// <summary>
        /// Calculate the hash-code from the bound value, unless the Option is in a None
        /// state, in which case the hash-code will be 0
        /// </summary>
        /// <returns>Hash-code from the bound value, unless the Option is in a None
        /// state, in which case the hash-code will be 0</returns>
        [Pure]
        public Task<int> GetHashCodeAsync() =>
            data.Map(a => a.GetHashCode());

        /// <summary>
        /// Get a string representation of the Option
        /// </summary>
        /// <returns>String representation of the Option</returns>
        [Pure]
        public override string ToString() =>
            ToStringAsync().Result;

        /// <summary>
        /// Get a string representation of the Option
        /// </summary>
        /// <returns>String representation of the Option</returns>
        [Pure]
        public Task<string> ToStringAsync() =>
            data.Map(toString);

        /// <summary>
        /// Is the option in a Some state
        /// </summary>
        [Pure]
        public Task<bool> IsSome =>
            data.Map(a => a.IsSome);

        /// <summary>
        /// Is the option in a None state
        /// </summary>
        [Pure]
        public Task<bool> IsNone =>
            data.Map(a => a.IsNone);

        /// <summary>
        /// Helper accessor for the bound value
        /// </summary>
        internal Task<A> Value =>
            data.Map(a => a.Value);

{'fraction_non_alphanumeric': 0.13824419778002017, 'fraction_numerical': 0.0011643250795622137, 'mean_word_length': 1.7135636057287278, 'pattern_counts': {'":': 0, '<': 241, '<?xml version=': 0, '>': 285, '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': '672029', 'n_tokens_mistral': 3539, 'n_tokens_neox': 3477, 'n_words': 1027}