Проблема в том, что в дотнетных дженериках интерфейс монады не выражается.
Т.е. нельзя записать функцию, которая работает с любой монадой — для этого нужен полиморфизм более высокого ранга.
Допустим, нам нужна функция, которая поднимает бинарную операцию в монаду. Т.е. если мы поднимаем в мэйби — у нас будет вычисление, которое равно результату бинарной опирации если оба аргумента Some и None, если один или больше аргументов бинарной опирации None, а если поднимаем в список, то у нас недетерминированное вычисление:
public static Func<?, ?, ?> Lift<TX, TY, TR>( Func<TX, TY, TR> f)
{
return (? mx, ? my) => from x in mx
from y in my
select f(x, y)
}
какие типы должны быть вместо "?" ?
//псевдошарп
public interface Monad<M> where M : * -> *
{
M<T> Return<T>(T a);
M<T2> Bind<T, TR>(M<T> a, Func<T1, M<TR>> f);
}
Это невозможно — абстрагироваться от конструктора типа дотнетные дженерики не позволяют — только от типа.
Ну а в Скале интерфейс монады записать можно:
trait Monad[M[_]] {
def return[A](a: A): M[A]
def bind[A, B](a: M[A], f: A => M[B]): M[B]
}
... << RSDN@Home 1.2.0 alpha 4 rev. 1446>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll