Я читаю книгу "Программирование в Хаскелле" Грэма Хаттона, и у меня есть некоторая проблема, чтобы понять, как <*>
и частичное приложение могут использоваться для синтаксического анализа строки.
Я знаю, что pure (+1) <*> Just 2
производит Just 3
потому что pure (+1)
создает Just (+1)
, а затем Just (+1) <*> Just 2
производит Just (2+1)
, а затем Just 3
Но в более сложном случае:
-- Define a new type containing a parser function
newtype Parser a = P (String -> [(a,String)])
-- This function apply the parser p on inp
parse :: Parser a -> String -> [(a,String)]
parse (P p) inp = p inp
-- A parser which return a tuple with the first char and the remaining string
item :: Parser Char
item = P (\inp -> case inp of
[] -> []
(x:xs) -> [(x,xs)])
-- A parser is a functor
instance Functor Parser where
fmap g p = P (\inp -> case parse p inp of
[] -> []
[(v, out)] -> [(g v, out)])
-- A parser is also an applicative functor
instance Applicative Parser where
pure v = P (\inp -> [(v, inp)])
pg <*> px = P (\inp -> case parse pg inp of
[] -> []
[(g, out)] -> parse (fmap g px) out)
Итак, когда я это сделаю:
parse (pure (\x y -> (x,y)) <*> item <*> item) "abc"
Ответ:
[(('a','b'),"c")]
Но я не понимаю, что именно происходит. Во-первых:
pure (\x y -> (x,y)) => P (\inp1 -> [(\x y -> (x,y), inp1)])
Теперь у меня есть парсер с одним параметром.
Тогда:
P (\inp1 -> [(\x y -> (x,y), inp1)]) <*> item
=> P (\inp2 -> case parse (\inp1 -> [(\x y -> (x,y), inp1)]) inp2 of ???
Я действительно не понимаю, что здесь происходит. Может кто-нибудь объяснить, шаг за шагом, что происходит сейчас, до конца, пожалуйста.