Новое в 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
? Есть ли какая-то неотъемлемая проблема, связанная с (что я считаю) более простым определением?