Я понимаю аргументацию подписи типа <$>
, так как это просто инфиксная версия 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
?