我讀格雷厄姆·赫頓在Haskell書編程和我有一些問題了解<*>
和部分應用程序如何被用來解析字符串。適用函子:<*>和部分應用程序,它是如何工作
我知道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 ???
我真的不明白這裏發生了什麼。 有人可以一步一步解釋,現在發生了什麼,直到最後。
fmap的定義存在一個小錯誤。它是「case parse p inp」而不是「case p inp」 – yaa
剛剛提交了一個編輯來修復這個問題(以及一些格式化)。 –
通過檢查'<*>'的定義,你能首先看到,左邊的解析器('pg')被應用到輸入,然後右邊的解析器('px')被應用到剩餘的應用左手語法分析器的字符串?那麼,你能看到'item'是一個總是消耗一個字符的解析器嗎?那麼,你能否看到「純粹的f」是一個消耗* no *輸入的解析器?我覺得這三件作品足以把答案放在一起。 – user2407038