2015-07-22 10 views
15

Jest to dobrze znany fakt, że (>>=) mogą być realizowane z wykorzystaniem fmap i join podczas join mogą być realizowane z wykorzystaniem >>=. Czy istnieje jakiś powód, dla którego nie zdefiniowaliśmy klasy Monad z join uwzględnionej i przy użyciu następujących domyślnych definicji?Dlaczego nie jest `join` część klasy` Monad`

join x = x >>= id 
x >>= f = join $ f <$> x 

Pozwoliłoby to minimalna definicja obejmuje też tylko (>>=) lub join, zamiast zmuszania (>>=). Może być trochę pomocna, biorąc pod uwagę teorię kategorii, która preferuje join.

Zwykłym argumentem przeciwko modyfikacji klas jest łamanie wstecznej zgodności. Jednak w tym przypadku tak by się nie stało - dodajemy tylko możliwość definiowania Monad przy użyciu join.

+1

Jak mówisz, '(>> =) = dołącz. fmap', ale przed GHC 7.10 'Monad' był * nie * automatycznie funktor. W tym sensie definiujemy zarówno 'join', jak i' fmap' w 'bind'. Dużo łatwiej jest też zaimplementować '>> =' niż dołączyć. Spróbuj zrobić to dla, powiedzmy, funktora parser/stan. – AJFarmar

+0

@AJFarmar Nie sądzę, że '(>> =) = dołącz. fmap' działa. Argumenty są odwracane i pojawiają się inne problemy. Ale dobre punkty! – Alec

+0

Ach, masz rację, to właściwie '(dołącz). flip fmap', ale pomysł był tam, jak mówisz. – AJFarmar

Odpowiedz

21

To miało się stać z Applicative-Monad proposal (która dotarła do GHC 7.10). Jest jednak a technical issue z udziałem type roles w GHC, który odroczył w nieskończoność realizację tego, co sugerujesz.

+6

I to jest straszny powód, aby wykluczyć 'dołączać'. Powinien być częścią klasy Monad. – augustss

+4

@augustss, to jest * smutny * powód, a nie * zły * jeden. Możliwość korzystania z generalizowanych wyprowadzeń nowych typów i koercji dla monad jest dobrą rzeczą. – dfeuer

+1

@dfeuer Jest tak, jak mówisz, ale można po prostu zdefiniować 'join' niezależnie, a następnie użyć tożsamości' (>> =) = (join.). odwróć fmap', jak wskazałem powyżej, więc nie stanowi to większego problemu. – AJFarmar

Powiązane problemy