我读格雷厄姆·赫顿在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