У меня есть этот монадический объект.
data Parser a = Parser (String -> Maybe (a, String))
instance Functor Parser where
-- fmap :: (a -> b) -> Parser a -> Parser b
fmap f (Parser pa) = Parser $ \input -> case pa input of
Nothing -> Nothing
Just (a, rest) -> Just (f a, rest)
instance Applicative Parser where
pure = return
(<*>) = ap
instance Monad Parser where
--return :: a -> Parser a
return a = Parser $ \input -> Just (a, input)
--(>>=) :: Parser a -> (a -> Parser b) -> Parser b
(Parser pa) >>= f = Parser $ \input -> case pa input of
Nothing -> Nothing
Just (a,rest) -> parse (f a) rest
И у меня есть это определение item
, которое, как мне говорят, «читается в символе», но я действительно не вижу никакого чтения.
item :: Parser Char
item = Parser $ \ input -> case input of "" -> Nothing
(h:t) -> Just (h, t)
Но ладно, ладно, может быть, я должен просто расслабиться, говоря о том, насколько буквально понимать слово «читать» и подшучивать над ним. Идем дальше, у меня есть
failParse :: Parser a
failParse = Parser $ \ input -> Nothing
sat :: (Char -> Bool) -> Parser Char
sat p = do c <- item
if p c
then return c
else failParse
И тут я совсем запутался. Что хранится в переменной c
? Поскольку item
— это Parser
с параметром Char
, мое первое предположение состоит в том, что c
хранит такой объект. Но после секундного размышления я понимаю, что теперь не работает нотация do
, вы не получаете монаду, вы получаете содержимое монады. Отлично, но тогда это говорит мне, что c
- это функция
\ input -> case input of "" -> Nothing
(h:t) -> Just (h, t)
Но очевидно, что это неправильно, так как следующая строка определения sat
рассматривает c
как символ. Мало того, что это не то, что я ожидал, но это примерно на три уровня структуры ниже, чем я ожидал! Это не функция, не объект Maybe
и не кортеж, а левая координата кортежа Just
, спрятанная внутри функции! Как этот маленький персонаж работает так далеко снаружи? Что указывает <-
извлечь эту часть монады?