Skip to content

Instantly share code, notes, and snippets.

@louthy
Last active February 27, 2020 21:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save louthy/a76bc757f5c850789be83538464f7aef to your computer and use it in GitHub Desktop.
Save louthy/a76bc757f5c850789be83538464f7aef to your computer and use it in GitHub Desktop.
[System.Serializable]
public sealed class Just<A> : Maybe<A>, System.IEquatable<Just<A>>, System.IComparable<Just<A>>, System.IComparable
{
public readonly A Value;
public Just(A Value)
{
this.Value = Value;
}
public static Just<A> New(A Value) => new Just<A>(Value);
public void Deconstruct(out A Value)
{
Value = this.Value;
}
private Just(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
this.Value = (A)info.GetValue("value", typeof(A));
}
public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
info.AddValue("value", this.Value);
}
public static bool operator ==(Just<A> x, Just<A> y) => ReferenceEquals(x, y) || (x?.Equals(y) ?? false);
public static bool operator !=(Just<A> x, Just<A> y) => !(x == y);
public static bool operator>(Just<A> x, Just<A> y) => !ReferenceEquals(x, y) && !ReferenceEquals(x, null) && x.CompareTo(y) > 0;
public static bool operator <(Just<A> x, Just<A> y) => !ReferenceEquals(x, y) && (ReferenceEquals(x, null) && !ReferenceEquals(y, null) || x.CompareTo(y) < 0);
public static bool operator >=(Just<A> x, Just<A> y) => ReferenceEquals(x, y) || (!ReferenceEquals(x, null) && x.CompareTo(y) >= 0);
public static bool operator <=(Just<A> x, Just<A> y) => ReferenceEquals(x, y) || (ReferenceEquals(x, null) && !ReferenceEquals(y, null) || x.CompareTo(y) <= 0);
public bool Equals(Just<A> other)
{
if (LanguageExt.Prelude.isnull(other))
return false;
if (!default(LanguageExt.ClassInstances.EqDefault<A>).Equals(this.Value, other.Value))
return false;
return true;
}
public override bool Equals(object obj) => obj is Just<A> tobj && Equals(tobj);
public int CompareTo(object obj) => obj is Maybe<A> p ? CompareTo(p) : 1;
public int CompareTo(Just<A> other)
{
if (LanguageExt.Prelude.isnull(other))
return 1;
int cmp = 0;
cmp = default(LanguageExt.ClassInstances.OrdDefault<A>).Compare(this.Value, other.Value);
if (cmp != 0)
return cmp;
return 0;
}
public override int GetHashCode()
{
const int fnvOffsetBasis = -2128831035;
const int fnvPrime = 16777619;
int state = fnvOffsetBasis;
unchecked
{
state = (default(LanguageExt.ClassInstances.HashableDefault<A>).GetHashCode(this.Value) ^ state) * fnvPrime;
}
return state;
}
public override string ToString()
{
var sb = new System.Text.StringBuilder();
sb.Append("Just(");
sb.Append(LanguageExt.Prelude.isnull(Value) ? $"Value: [null]" : $"Value: {Value}");
sb.Append(")");
return sb.ToString();
}
A Maybe<A>.Just(A value) => throw new System.NotSupportedException();
Unit Maybe<A>.Nothing() => throw new System.NotSupportedException();
}
[System.Serializable]
public sealed class Nothing<A> : Maybe<A>, System.IEquatable<Nothing<A>>, System.IComparable<Nothing<A>>, System.IComparable
{
public Nothing()
{
}
public static Nothing<A> New() => new Nothing<A>();
public void Deconstruct()
{
}
private Nothing(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
}
public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
}
public static bool operator ==(Nothing<A> x, Nothing<A> y) => ReferenceEquals(x, y) || (x?.Equals(y) ?? false);
public static bool operator !=(Nothing<A> x, Nothing<A> y) => !(x == y);
public static bool operator>(Nothing<A> x, Nothing<A> y) => !ReferenceEquals(x, y) && !ReferenceEquals(x, null) && x.CompareTo(y) > 0;
public static bool operator <(Nothing<A> x, Nothing<A> y) => !ReferenceEquals(x, y) && (ReferenceEquals(x, null) && !ReferenceEquals(y, null) || x.CompareTo(y) < 0);
public static bool operator >=(Nothing<A> x, Nothing<A> y) => ReferenceEquals(x, y) || (!ReferenceEquals(x, null) && x.CompareTo(y) >= 0);
public static bool operator <=(Nothing<A> x, Nothing<A> y) => ReferenceEquals(x, y) || (ReferenceEquals(x, null) && !ReferenceEquals(y, null) || x.CompareTo(y) <= 0);
public bool Equals(Nothing<A> other)
{
if (LanguageExt.Prelude.isnull(other))
return false;
return true;
}
public override bool Equals(object obj) => obj is Nothing<A> tobj && Equals(tobj);
public int CompareTo(object obj) => obj is Maybe<A> p ? CompareTo(p) : 1;
public int CompareTo(Nothing<A> other)
{
if (LanguageExt.Prelude.isnull(other))
return 1;
return 0;
}
public override int GetHashCode()
{
return 0;
}
public override string ToString()
{
return "Nothing";
}
A Maybe<A>.Just(A value) => throw new System.NotSupportedException();
Unit Maybe<A>.Nothing() => throw new System.NotSupportedException();
}
public static partial class Maybe
{
public static Maybe<A> Just<A>(A value) => new Just<A>(value);
public static Maybe<A> Nothing<A>() => new Nothing<A>();
public static Maybe<B> Bind<A, B>(this Maybe<A> ma, System.Func<A, Maybe<B>> f) => ma switch
{
Just<A> v => f(v.Value),
Nothing<A> v => new Nothing<B>(),
_ => throw new System.NotSupportedException()
};
public static Maybe<B> Map<A, B>(this Maybe<A> ma, System.Func<A, B> f) => Maybe<A>.Map(ma, f);
public static Maybe<B> Select<A, B>(this Maybe<A> ma, System.Func<A, B> f) => Map(ma, f);
public static Maybe<B> SelectMany<A, B>(this Maybe<A> ma, System.Func<A, Maybe<B>> f) => Bind(ma, f);
public static Maybe<C> SelectMany<A, B, C>(this Maybe<A> ma, System.Func<A, Maybe<B>> bind, System.Func<A, B, C> project) => Bind(ma, a => Map(bind(a), b => project(a, b)));
public static Maybe<A> Flatten<A>(this Maybe<Maybe<A>> mma) => Bind(mma, LanguageExt.Prelude.identity);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment