2013-06-10 15 views
10

According to the Haskell wikibook, A Monad nazywa m jest Functor z dwóch dodatkowych operacji:To nie jest monada, ale co to jest?

unit :: a -> m a 
join :: m (m a) -> m a 

To miłe, ale mam coś nieco innego. Połyskując krwawymi szczegółami, mam typ, który ma dobre funkcje unit i join, ale jego fmap nie jest dobrze zachowywany (fmap g . fmap f niekoniecznie jest). Z tego powodu nie można go wykonać jako instancji o numerze Monad. Niemniej jednak chciałbym dać mu jak najwięcej ogólnych funkcji.

Moje pytanie brzmi, jakie struktury teoretyczne kategorii są podobne do monad, ponieważ mają one unit i join?

Zdaję sobie sprawę, że na pewnym poziomie powyższe pytanie jest źle zdefiniowane. W przypadku monad definicje unit i join mają sens tylko pod względem definicji fmap. Bez fmap nie można zdefiniować żadnego z praw monady, więc wszelkie definicje z zakresu unit/join będą równie "poprawne". Tak więc szukam funkcji innych niż fmap, że może być sens zdefiniowanie praw "not-monad" w tych funkcjach unit i join.

+5

można opisać więcej o strukturze masz, a co w szczególności powoduje jego uszkodzenie prawo Fusion for 'fmap'? – luqui

+2

Przypuszczam, że konkretnie "poprawiłeś" 'fmap' w taki sposób, że' join' spełnia drugie prawo monady? Normalnie prawie zawsze dostajesz 'fmap g. fmap f ≡ fmap $ f.g' po prostu automatycznie. – leftaroundabout

+0

@luqui Bardziej interesuję się pojęciem ogólnym niż tylko tym konkretnym przypadkiem, ale jest to normalna dystrybucja. Jeśli myślisz o 'fmap' jako stosowaniu funkcji do każdego punktu w dystrybucji, to' fmap' spełnia jedynie prawa 'Functor' dla dodawania i mnożenia. 'unit' trenuje na jednym punkcie danych, a' join' łączy "normalny rozkład normalnych rozkładów" w pojedynczą normalną dystrybucję. Oczywiście, wymaga to pewnych ograniczeń parametrów, więc nie można tego w ogóle zrobić za pomocą klas typu "Base" i używam 'ConstraintKinds', aby się z nim bawić. –

Odpowiedz

3

Cóż, tutaj jest jedno prawo, które powinieneś mieć tylko z unit i join. Biorąc x :: m a,

join (unit x) = x 

Aby pokazać, że to nie tylko pochodzić znikąd, zacznijmy z istniejącym prawem monady:

return x >>= f = f x 

Zważywszy, że m >>= f = join (fmap f m)

join (fmap f (return x)) = f x 

Wybierz opcję f = id

join (fmap id (return x)) = id x 

Użyj prawo funktora że fmap id = id

join (id (return x)) = id x 

Użyj oczywiste id a = a

join (return x) = x