Новое в Haskell, и я пытаюсь понять эту вещь Монады. Оператор монадического связывания - >>= - имеет очень своеобразную подпись типа:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Чтобы упростить, заменим Maybe на m:
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
Однако обратите внимание, что определение могло быть записано тремя различными способами:
(>>=) :: Maybe a -> (Maybe a -> Maybe b) -> Maybe b
(>>=) :: Maybe a -> ( a -> Maybe b) -> Maybe b
(>>=) :: Maybe a -> ( a -> b) -> Maybe b
Из трех один в центре является наиболее асимметричным. Тем не менее, я понимаю, что первый из них не имеет смысла, если мы хотим избежать (то, что LYAH вызывает шаблонный код). Однако из следующих двух я предпочел бы последний. Для Maybe это будет выглядеть так:
Если это определено как:
(>>=) :: Maybe a -> (a -> b) -> Maybe b
instance Monad Maybe where
Nothing >>= f = Nothing
(Just x) >>= f = return $ f x
Здесь a -> b - обычная функция. Кроме того, я не вижу ничего опасного, потому что Nothing ловит исключение перед приложением функции, поэтому функция a -> b не будет вызываться, если не получена Just a.
Так что, возможно, есть что-то, что не кажется мне очевидным, что привело к тому, что определение (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b было предпочтительнее более простого определения (>>=) :: Maybe a -> (a -> b) -> Maybe b? Есть ли какая-то неотъемлемая проблема, связанная с (что я считаю) более простым определением?