2009-11-10 13 views
28

... z tymi wszystkimi nowymi (i nie tak nowymi, jeśli liczymy IEnumerable) rzeczami związanymi z monadą?Dlaczego nie ma czegoś takiego jak IMonad <T> w nadchodzącym .NET 4.0

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

Pozwoliłoby to na pisanie funkcji działających na dowolnym monadycznym typie. Czy to nie jest tak ważne?

+5

Eric Lippert wyjaśnia, dlaczego niektóre funkcje nie są realizowane w ramach: http://stackoverflow.com/questions/1331739/enum-type-constraints-in-c/1331811#1331811 –

Odpowiedz

61

Pomyśl o tym, jaki powinien być podpis dla metod IMonad<T>. W Haskell typeclass Monada jest zdefiniowany jako

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

To trudne do przetłumaczenia tego bezpośrednio do interfejsu C#, bo trzeba być w stanie odnosić się do konkretnego wdrażania podtyp („mA” lub ISpecificMonad<a>) w ramach definicji ogólna Interfejs IMonad. OK, zamiast próbować bezpośrednio (na przykład) IEnumerable<T> implementować bezpośrednio obiekt IMonad<T>, spróbujemy rozważyć implementację IMonad w oddzielnym obiekcie, który może zostać przekazany, wraz z konkretną instancją typu monad, do wszystkiego, co należy traktować jako monada (jest to "styl przekazywania słownika"). Będzie to IMonad<TMonad>, a TMonad tutaj nie będzie T w IEnumerable<T>, ale sama w sobie będzie to IEnumerable<T>, ale IEnumerable<T>. Ale czekaj - to też nie działa, ponieważ na przykład podpis Return<T> na przykład musi nas od dowolny typ T do TMonad<T>, dla dowolnyTMonad<>. IMonad musiałaby być zdefiniowana jako coś jak

interface IMonad<TMonad<>> { 

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

używając hipotetyczny funkcji C#, który pozwoli nam wykorzystać typu konstruktorów (jak TMonad <>) jako parametry typu rodzajowego. Ale oczywiście C# nie ma tej funkcji (polimorfizm wyższego płaszcza). Można rektyfikować konstruktory typów w czasie wykonywania (typeof(IEnumerable<>)), ale nie mogą odwoływać się do nich w podpisach typów bez podawania im parametrów. Tak więc poza rzeczami -100 punktów, wdrożenie tego "poprawnie" wymagałoby nie tylko dodania kolejnej zwykłej definicji interfejsu, ale także głębokich dodatków do systemu typów.

Dlatego zdolność do ułatwienia składni zapytań nad własnymi typami jest rodzaj hacked on (oni po prostu „magicznie” pracy, jeśli istnieją odpowiednie magiczne nazwy metod z odpowiednimi podpisami) zamiast używać mechanizmu interfejsu itp

+10

Dobra odpowiedź, oto krótka wersja: "nie da się zdefiniować Monady w C#, system typów nie jest wystarczająco wydajny" :) –

+0

Tak, może w CLR 5.0 lub 6.0 lub w środowisku post .NET wyższego poziomu abstrakcji. –

+2

W mojej osobistej opinii, bez statycznie sprawdzonych efektów ubocznych (tj. Czystych funkcji), trafiłeś w punkt poważnie zmniejszających się zysków, dodając raczej wyrafinowanie do systemu typów raczej szybko. Prawdziwą korzyścią zaawansowanego systemu typów jest możliwość ustalenia złożonych właściwości/niezmienników twojego programu, które udowodniono we wszystkich przypadkach (w przeciwieństwie do testowania ich w pewnych przypadkach i heurystycznie ekstrapolowane), ale jeśli jakaś funkcja ma dodatkowy nieograniczony "kanał" dla wejścia/wyjścia, który jest niezaznaczony przez system typów, nie ma wiele do udowodnienia. –

-18

Monady po prostu nie są ważne dla programistów .NET. Nie wiedząc nawet, że istnieją monady, nadal można zbudować framework LINQ. Co ważniejsze, nie wyglądałoby to inaczej. Nie ma znaczenia, czy myślisz w kategoriach monad (Haskell), przepisywania drzewa wyrażenia (Lisp), operacji bazujących na zestawie (SQL), czy używania map/reduce do tworzenia nowych typów (Ruby, Python), efekt końcowy jest będzie takie samo.

W rzeczywistości posunąłbym się do stwierdzenia, że ​​monady są wręcz bezużyteczne dla programistów .NET. Za każdym razem, gdy widzę bibliotekę dla .NET opartą na monadach, jest ona niezmiennie zarówno bardziej szczegółowa, jak i mniej zrozumiała niż prosty kod C# lub VB. Powód jest prosty, języki takie jak C# i VB są zbudowane na znacznie, o wiele potężniejszych cegiełkach niż języki takie jak Haskell.

Haskell w szczególności musi używać monad na wszystko, ponieważ to wszystko, co mają. To samo dotyczy makr w Lisp lub dynamicznego pisania w JavaScript. Kiedy masz jednomyślnego kucyka, ta sztuczka musi być całkiem niezła.

On LINQ, Monads, and the Blindness of Power

+15

_ "Powód jest prosty, języki takie jak C# i VB są zbudowane na o wiele mocniejszych cegiełkach niż języki takie jak Haskell." Mówiąc to pokazuje, że nigdy nie zaprogramowałeś w Haskell lub nie nauczyłeś się w pełni jego pojęć. –

+2

Zasługuje na downvotes, choćby za dodanie linku do "prywatnego bloga". –

+1

To nie zasługuje na obniżenie. Pytanie i tak wymaga poglądowej opinii. Podał prawidłowe powody, dla których monady należą do C#. – usr

Powiązane problemy