I have started putting together a functional programming library in C# which is somewhat inspired by scalaz and the book Functional Programming in Scala.I am hoping to get some feedback on the Monad Transformers implementations and comments.Please understand this is implemented in C# and .NET, which does not support typeclasses and Higher Kindedness.Here is an example demo of what I have been able to create so far with what has been developed.using NUnit.Framework;using System;using System.Collections.Generic;using System.Threading;using System.Linq;namespace Sharper.Tests{    internal class Student    {        public int Id{ get; set; }        public string Name{ get; set; }    }    internal class Score    {        public int StudentId{ get; set; }        public string Name{ get; set; }        public Decimal Result{ get; set; }    }    internal class ScoreServer    {        public ScoreServer()        {            students = new Dictionary<int, Student>();            scores = new Dictionary<int, List<Score>>();            students.Add(1, new Student{ Id = 1, Name = Blair });            students.Add(2, new Student{ Id = 2, Name = Esther });            scores.Add(1, new List<Score> {                 new Score{ StudentId = 1, Name = Maths, Result = 76 },                new Score{ StudentId = 1, Name = English, Result = 56 },                new Score{ StudentId = 1, Name = Science, Result = 67 }            });            scores.Add(2, new List<Score> {                 new Score{ StudentId = 2, Name = Maths, Result = 87 },                new Score{ StudentId = 2, Name = English, Result = 72 },                new Score{ StudentId = 2, Name = Science, Result = 59 }            });        }        public IO<String> GetStudentScoreFor(int studentId, string classname)        {            var studentT = GetStudentById(studentId).OptionT();            var studentNameT = studentT.Map(x => x.Name)                                       .OrElse(new Some<string>(studentId.ToString()));            var matchedScoreT = from student in studentT                                         from score in GetClassScoreByStudent(student.ToOption(), classname).OptionT()                                         select String.Format(Student: {0} Recieved {1} for {2}, student.Name, score.Name, score.Result);            var result = from name in studentNameT                                  from text in matchedScoreT.Map(score => score)                                                   .OrElse(String.Format(Student {0} has not record for {1}, name, classname)                                                   .ToOption())                                  select text;            return result.GetValueOrDefault(String.Empty);        }        public IO<Option<Student>> GetStudentById(int studentId)        {            return new IO<Option<Student>>(                () => {                    Thread.Sleep(TimeSpan.FromSeconds(1.5)); // Simulate work                    return students.SafeGet(studentId);                }            );        }        public IO<Option<Score>> GetClassScoreByStudent(Option<Student> student, string @class)        {            return new IO<Option<Score>>(                () => {                    Thread.Sleep(TimeSpan.FromSeconds(1)); // Simulate work                    return student.FlatMap(x => scores.SafeGet(x.Id)                                  .FlatMap(y => y.FirstOrDefault(z => z.Name == @class)                                  .ToOption()));                }            );        }        private Dictionary<int,Student> students{ get; set; }        private Dictionary<int, List<Score>> scores { get; set; }    }    [TestFixture]    public class OptionIODemoTests    {        [Test]        public void Testing_ScoreServer1()        {            var server = new ScoreServer();            var result = server.GetStudentScoreFor(1, Maths).PerformUnsafeIO();            Assert.AreEqual(String.Format(Student: {0} Recieved {1} for {2}, Blair, Maths, 76), result);        }        [Test]        public void Testing_ScoreServer2()        {            var server = new ScoreServer();            var result = server.GetStudentScoreFor(1, Mathematics).PerformUnsafeIO();            Assert.AreEqual(String.Format(Student {0} has not record for {1}, Blair, Mathematics), result);        }        [Test]        public void Testing_ScoreServer3()        {            var server = new ScoreServer();            var result = server.GetStudentScoreFor(3, Mathematics).PerformUnsafeIO();            Assert.AreEqual(String.Format(Student {0} has not record for {1}, 3, Mathematics), result);        }    }}The main projects site is here.
Functional Programming Library
c#;functional programming;monads