Я понимаю аргументацию подписи типа <$>, так как это просто инфиксная версия fmap, но, сравнивая ее с тиковой подписью >>=, это делает меня намного менее понятным.
Сначала установите, что я имею в виду.
(>>=) :: 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
Посмотрев на типы сигнатур, мы увидим, что >>= берет значение слева, а функцию справа, что имеет большой смысл, если вы считаете его свойство цепочки: foo >>= bar >>= baz
Что заставляет меня задаваться вопросом, почему бы не <*> и <$> сделать это тоже? вы не можете написать foo <*> bar <*> baz, потому что для вывода foo <*> bar для вывода будет функция, а не значение.
Я знаю, что существуют <**> и =<<, которые оба переворачивают порядок параметров, позволяя мне делать что-то вроде:
Just 4 <**> pure (+3) <**> pure (*2) >>= (\x -> Just (x-3))
Что могло бы быть красиво сведено к:
Just 4 <$$> (+3) <$$> (*2) >>= (\x -> Just (x-3))
Если <$$> существовало, или если порядок параметров <$> и <*> был отменен.
Еще одна вещь, которая заставляет меня задаться вопросом, почему существует разница, заключается в том, что для новичков становится труднее привыкнуть и/или помнить, является ли это функцией или значением, которое на первом месте, без необходимости искать его.
Итак, почему это в случаях <*> и <$> it fn op val, но с >>= it val op fn?