Rozumiem rozumowanie sygnatury typu <$>
, ponieważ jest to tylko wersja infiksowa fmap
, ale porównanie jej z sygnaturą typu >>=
ma dla mnie dużo mniejszy sens.
Najpierw ustalmy, co przez to rozumiem.
(>>=) :: Monad m => m a -> (a -> m b) -> m b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
(<$>) :: Functor f => (a -> b) -> f a -> f b
Patrząc na podpisami typu możemy zobaczyć, że >>=
przyjmuje wartość po lewej stronie, a funkcja po prawej stronie, co sprawia, że wiele sensu, jeśli wziąć pod uwagę jego właściwość łańcuchowy: foo >>= bar >>= baz
Która Prowadzi mnie do zastanawiania się, dlaczego nie robisz tego też? nie można pisać foo <*> bar <*> baz
, ponieważ wymagałoby to, aby wyjście foo <*> bar
było funkcją, a nie wartością.
wiem, że <**>
i =<<
istnieć że zarówno odwrócić kolejność parametrów, pozwalając mi zrobić coś takiego:
Just 4 <**> pure (+3) <**> pure (*2) >>= (\x -> Just (x-3))
co mogło być pięknie zmniejszone do:
Just 4 <$$> (+3) <$$> (*2) >>= (\x -> Just (x-3))
Jeśli <$$>
istniał, lub jeśli kolejność parametrów <$>
i <*>
została odwrócona.
Inną rzeczą, która sprawia, że zastanawiam się, dlaczego istnieje różnica, jest to, że utrudniają początkującym przyzwyczajenie się i/lub zapamiętanie, czy to funkcja, czy wartość, która jest najważniejsza, bez konieczności sprawdzania.
Więc dlaczego jest tak, że w przypadkach <*>
i <$>
to fn op val
ale z >>=
to val op fn
?
ale często chcesz dokładnie to z 'Applicatives' : na przykład '(+) <$> Tylko 5 <*> Tylko 5 ' <- nie jest tym, że "Po prostu" piękne;) – Carsten
'(>> =)' konstruuje łańcuchy "w stylu imperatywnym" (w przeciwnym razie zastanawialibyśmy się, dlaczego to nie jest w takiej samej kolejności jak '$'). '(<= <)' pozwala również na łańcuchowanie - "' (.) 'styl". '(<*>)' jest przydatne do "stosowania" funkcji wielu argumentów - dostarczając argumenty w kolejności deklaracji. –
Prawdziwe pytanie brzmi, dlaczego '(>> =)' używa prawie odwrotnego porządku od wszystkiego w Haskell. Typ '(= <<) :: Monad m => (a -> mb) -> (ma -> mb)' wygląda bardziej jak wszystko inne w Haskell niż '' (>> =) = odwróć (= <<) '. –