Почему в следующей версии .NET 4.0 нет ничего похожего на IMonad <T> - PullRequest
29 голосов
/ 10 ноября 2009

... со всеми этими новыми (и не такими уж новыми, если считать IEnumerable) связанными с монадами вещами?

interface IMonad<T>
{
 SelectMany/Bind();
 Return/Unit();
}

Это позволит писать функции, которые работают с любым монадическим типом. Или это не так критично?

Ответы [ 2 ]

63 голосов
/ 15 ноября 2009

Подумайте, какой должна быть подпись для методов IMonad<T>. В Haskell класс типов Monad определяется как

class Monad m where
  (>>=) :: m a -> (a -> m b) -> m b
  return :: a -> m a

Сложно перевести это непосредственно на интерфейс C #, потому что вы должны иметь возможность ссылаться на конкретный подтип реализации ("m a" или ISpecificMonad<a>) в определении общего интерфейса IMonad. Хорошо, вместо того, чтобы пытаться (например) IEnumerable<T> реализовать IMonad<T> напрямую, мы попытаемся выделить реализацию IMonad в отдельный объект, который может быть передан вместе с конкретным экземпляром типа монады тому, что нужно рассматривайте это как монаду (это «стиль передачи словаря»). Это будет IMonad<TMonad>, а TMonad здесь будет не буквой T в IEnumerable<T>, а самой IEnumerable<T>. Но подождите - это тоже не может работать, потому что, например, подпись Return<T> должна привести нас от любого типа T к TMonad<T>, для любого TMonad<>. IMonad должен быть определен как что-то вроде

interface IMonad<TMonad<>> {

    TMonad<T> Unit<T>(T x);
    TMonad<U> SelectMany<T, U>(TMonad<T> x, Func<T, TMonad<U>> f);
}

с использованием гипотетической функции C #, которая позволила бы нам использовать конструкторы типов (например, TMonad <>) в качестве параметров универсального типа. Но, конечно, C # не имеет этой функции (полиморфизм с более высоким родом) . Вы можете модифицировать конструкторы типов во время выполнения (typeof(IEnumerable<>)), но не можете ссылаться на них в сигнатурах типов без указания параметров. Таким образом, помимо -100 баллов, реализация этого «правильно» потребует не просто добавления другого обычного определения интерфейса, но и глубоких дополнений к системе типов.

Именно поэтому возможность иметь понимание запросов по вашим собственным типам взломана (они просто «магически» работают, если есть правильные имена магических методов с правильными сигнатурами) вместо использования механизма интерфейса и т. Д.

0 голосов
/ 15 ноября 2009

Монады просто не важны для программистов .NET. Даже не зная, что существуют монады, вы все равно можете построить каркас LINQ. Что еще более важно, это не выглядело бы иначе. Неважно, если вы думаете с точки зрения монад (Haskell), переписывания дерева выражений (Lisp), операций на основе множеств (SQL) или использования map / lower для создания новых типов (Ruby, Python), конечный результат: будет то же самое.

На самом деле, я бы сказал, что монады совершенно бесполезны для разработчиков .NET. Каждый раз, когда я вижу библиотеку для .NET, основанную на монадах, она неизменно одновременно более многословна и менее понятна, чем прямой код C # или VB. Причина проста: такие языки, как C # и VB, построены на гораздо более мощных строительных блоках, чем такие языки, как Haskell.

В частности, Хаскеллу нужно использовать монады для всего, потому что это все, что у них есть. То же самое касается макросов в Лиспе или динамической типизации в JavaScript. Когда у вас пони с одним трюком, этот трюк должен быть чертовски хорош.

О LINQ, монадах и слепоте власти

...