Skip to content

Instantly share code, notes, and snippets.

@Sov3rain
Last active April 13, 2022 15:42
Show Gist options
  • Save Sov3rain/f503f44ca0e4b2f22c3b0ebf19a93a25 to your computer and use it in GitHub Desktop.
Save Sov3rain/f503f44ca0e4b2f22c3b0ebf19a93a25 to your computer and use it in GitHub Desktop.
Monad in c#
using System;
void Main()
{
string foo = "Hello";
// a.then(f).then(g).then(j)
foo.Then(x => x.Trim().Ret())
.Then(x => x.Substring(0, 5).Ret())
.Then(x => x.Length.Ret())
.Then(x => (x * x).Ret())
.Value
.Dump(); // Dump is basically a chained 'Console.WriteLine' call.
}
// Nil or also called Identity
public struct Identity<T>
{
public Identity(T value) => Value = value;
public T Value { get; set; }
public bool HasValue => Value != null;
}
public static class Extensions
{
// Abbreviation for 'To Nil' or ToNil. Can be called Return or ret in other languages
public static Nil<T> Ret<T>(this T value) => new Nil<T>(value);
// Bind is also known as 'then' or 'ContinueWith' in other programming languages
// a.then(f).then(g).then(j)
public static Nil<TOut> Then<TIn, TOut>(this TIn @this, Func<TIn, Nil<TOut>> fn)
=> @this.Ret().Then(fn);
// f(a).then(g).then(j)
public static Nil<TOut> Then<TIn, TOut>(this Nil<TIn> @this, Func<TIn, Nil<TOut>> fn)
=> @this.HasValue ? fn(@this.Value) : new Nil<TOut>();
}
using System;
void Main()
{
string foo = "Hello";
foo.Bind(x => x.Trim().Nil())
.Bind(x => x.Substring(0, 5).Nil())
.Bind(x => x.Length.Nil())
.Bind(x => (x * x).Nil())
.Value
.Dump();
}
public struct Nil<T>
{
public Nil(T value) => Value = value;
protected Nil() { }
public T Value { get; set; }
public virtual bool HasValue => true;
public static Nil<T> Nothing = new Nothing<T>();
}
public struct Nothing<T> : Nil<T>
{
public override bool HasValue => false;
}
public static class Extensions
{
// // Abbreviation for 'To Nil' or ToNil. Also called Return or ret in other languages.
public static Nil<T> Nil<T>(this T value) => new Nil<T>(value);
// Bind is also known as 'then' or 'ContinueWith' in other programming languages
// a.then(f).then(g).then(j)
public static Nil<C> Bind<B, C>(this B b, Func<B, Nil<C>> fn)
=> b.Ret().Bind(fn);
public static Nil<C> Bind<B, C>(this Nil<B> b, Func<B, Nil<C>> fn)
=> b.HasValue ? fn(b.Value) : Nil<C>.Nothing;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment