Last active
March 1, 2017 13:07
-
-
Save acple/95d87353f31b2ffbe81a2cdb5a10502b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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