Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
using System;
using System.Collections.Generic;
using System.Linq;
namespace Test
{
class Program
{
static void Main(string[] args)
{
new FunctorTest().Test();
new MonadTest().Test(new List<int> { 10, 11, 12 });
return;
}
}
public struct Maybe<T>
{
public T Value { get; }
public bool HasValue { get; }
public Maybe(T value)
{
this.Value = value;
this.HasValue = true;
}
}
// Functor
// public shape Functor<F<A>>
// {
// F<B> Map<B>(Func<A, B> f);
// }
interface Functor<FA, A, FB, B>
{
FB Map(FA @this, Func<A, B> f);
}
// public extension MaybeFunctor<T> of Maybe<T> : Functor<Maybe<T>>
// {
// public Maybe<U> Map<U>(Func<T, U> f)
// => (this.HasValue) ? new Maybe<U>(f(this.Value)) : new Maybe<U>();
// }
struct MaybeFunctor<T, U> : Functor<Maybe<T>, T, Maybe<U>, U>
{
public Maybe<U> Map(Maybe<T> @this, Func<T, U> f)
=> (@this.HasValue) ? new Maybe<U>(f(@this.Value)) : new Maybe<U>();
}
// public extension ListFunctor<A> of List<A> : Functor<List<A>>
// {
// public List<B> Map<B>(Func<A, B> f)
// => this.Select(f).ToList();
// }
struct ListFunctor<A, B> : Functor<List<A>, A, List<B>, B>
{
public List<B> Map(List<A> @this, Func<A, B> f)
=> @this.Select(f).ToList();
}
class FunctorTest
{
// public F<object> Method<F<A>>(F<A> functor) where F<A> : Functor<F<A>>
// {
// var map1 = functor.Map(x => x.ToString());
// var map2 = map1.Map(_ => null as object);
// return map2;
// }
public FC Method<FA, A, FAImpl, FB, FBImpl, FC>(FA functor)
where FAImpl : struct, Functor<FA, A, FB, string>
where FBImpl : struct, Functor<FB, string, FC, object>
{
var impl = new FAImpl();
var map1 = impl.Map(functor, x => x.ToString());
var impl2 = new FBImpl();
var map2 = impl2.Map(map1, _ => null as object);
return map2;
}
//public List<object> Test()
// => Method<List<int>>(new List<int> { 1, 2, 3 });
public List<object> Test()
=> Method<
List<int>,
int,
ListFunctor<int, string>,
List<string>,
ListFunctor<string, object>,
List<object>>
(new List<int> { 1, 2, 3 });
}
// Monad
//public shape Monad<M<A>> : Functor<M<A>>
//{
// static M<A> Return(A value);
// // static M<A> Fail();
// M<B> Bind<B>(Func<A, M<B>> function);
//}
interface Monad<MA, A, MB, B> : Functor<MA, A, MB, B>
{
MA Return(A value);
// MA Fail();
MB Bind(MA @this, Func<A, MB> function);
}
//public extension ListMonad<A> of List<A> : Monad<List<A>>
//{
// public static List<A> Return(A value)
// => new List<A> { value };
// public List<B> Bind<B>(Func<A, List<B>> function)
// => this.SelectMany(function).ToList();
//}
struct ListMonad<A, B> : Monad<List<A>, A, List<B>, B>
{
public List<A> Return(A value)
=> new List<A> { value };
public List<B> Bind(List<A> @this, Func<A, List<B>> function)
=> @this.SelectMany(function).ToList();
// functor
public List<B> Map(List<A> @this, Func<A, B> f)
=> @this.Select(f).ToList();
}
class MonadTest
{
//public M<(A, string)> Method<M<A>>(M<A> monad) where M<A> : Monad<M<A>>
//{
// var monad2 = monad.Map(x => x.ToString());
// var monad3 = monad.Bind(x => monad2.Map(y => (x, y)));
// return monad3;
//}
public MC Method<MA, A, MAImpl, MB, MAImpl2, MBImpl, MC>(MA monad)
where MAImpl : struct, Monad<MA, A, MB, string>
where MAImpl2 : struct, Monad<MA, A, MC, (A, string)>
where MBImpl : struct, Monad<MB, string, MC, (A, string)>
{
var impl = new MAImpl();
var monad2 = impl.Map(monad, x => x.ToString());
var impl2 = new MAImpl2();
var monad3 = impl2.Bind(monad, x => { var impl3 = new MBImpl(); return impl3.Map(monad2, y => (x, y)); });
return monad3;
}
//public List<(A, string)> Test<A>(List<A> monad)
// => Method(monad);
public List<(A, string)> Test<A>(List<A> monad)
=> Method<
List<A>,
A,
ListMonad<A, string>,
List<string>,
ListMonad<A, (A, string)>,
ListMonad<string, (A, string)>,
List<(A, string)>>
(monad);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.