Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Created September 30, 2011 19:17
Show Gist options
  • Select an option

  • Save hodzanassredin/1254715 to your computer and use it in GitHub Desktop.

Select an option

Save hodzanassredin/1254715 to your computer and use it in GitHub Desktop.
secont implementation of monad
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Monad;
namespace Monad
{
public interface Polymorph<T>
{
}
public interface IMonad
{
Polymorph<B> Bind<A, B>(Polymorph<A> a, Func<A, Polymorph<B>> f);
Polymorph<A> Return<A>(A a);
}
public class MyList<T> : List<T>, Polymorph<T>
{
public MyList()
{
}
public MyList(List<T> from)
{
this.AddRange(from);
}
}
public class ListMonad : IMonad
{
public Polymorph<B> Bind<A, B>(Polymorph<A> a, Func<A, Polymorph<B>> f)
{
var res = new MyList<B>();
foreach (var item in (a as MyList<A>))
{
try
{
res.AddRange(f(item) as MyList<B>);
}
catch { }
}
return res;
}
public Polymorph<A> Return<A>(A a)
{
var res = new MyList<A>();
res.Add(a);
return res;
}
}
class Program
{
static void Main(string[] args)
{
var result = new ListMonad()
.ReturnStart("c:\\")
.Do(x => Directory.GetDirectories(x).ToML())
.Do(x => Directory.GetDirectories(x).ToML())
.Do(x => Directory.GetDirectories(x).Select(y=>y.Length).ToML())
.DoReturn<int, int, MyList<int>>(x=>x.Sum())//this one
.Finish<int, MyList<int>>();// and this one херня потомучто голова уже болит думать как грамотно сделать кастование
foreach (var item in result)
{
Console.WriteLine(item);
}
Console.ReadLine();
}
}
public static class Exts
{
public static MyList<T> ToML<T>(this IEnumerable<T> source)
{
return new MyList<T>(source.ToList());
}
public static Tuple<Polymorph<A>, IMonad> ReturnStart<A>(this IMonad monad, A init)
{
return new Tuple<Polymorph<A>, IMonad>(monad.Return(init), monad);
}
public static Tuple<Polymorph<A>, IMonad> Start<ACONT, A, B>(this IMonad monad, Polymorph<A> init)
{
return new Tuple<Polymorph<A>, IMonad>(init, monad);
}
public static P Finish<A, P>(this Tuple<Polymorph<A>, IMonad> prev)
where P : class, Polymorph<A>
{
return prev.Item1 as P;
}
public static Tuple<Polymorph<B>, IMonad> Do<A, B>(this Tuple<Polymorph<A>, IMonad> prev, Func<A, Polymorph<B>> f)
{
return new Tuple<Polymorph<B>, IMonad>(prev.Item2.Bind(prev.Item1, f), prev.Item2);
}
public static Tuple<Polymorph<B>, IMonad> DoReturn<A, B, P>(this Tuple<Polymorph<A>, IMonad> prev, Func<P, B> f)
where P : class, Polymorph<A>
{
return new Tuple<Polymorph<B>, IMonad>(prev.Item2.Return(f(prev.Item1 as P)), prev.Item2);
}
public static Tuple<Polymorph<A>, IMonad> DoFor<A>(this Tuple<Polymorph<A>, IMonad> prev, Func<A, Polymorph<A>> f, int times)
{
if (times < 1) throw new ArgumentException();
var res = prev.Item1;
for (int i = 0; i < times - 1; i++)
{
res = prev.Item2.Bind(res, f);
}
return new Tuple<Polymorph<A>, IMonad>(res, prev.Item2);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment