我正在尝试为数据Person(Sublayer
)编写解析器。但是我必须使用data Person
和<$>
在一行中编写它并且我尝试了很多,但我真的“过度”了。
解析器类型与往常一样:
<*>
我有这个功能:
newtype Parser a = Parser (String -> [(a,String)])
返回第一个完整的解析。
例如
如果我有这个简单的功能:
parse :: Parser a -> String -> Maybe a
如果我运行upper :: Parser Char
upper = satisfy isUpper
,我会parse upper "A"
我也有这样一个有趣的功能:
Just 'A'
,正如您所看到的,它接受所有字符串的字符串并以大写字母开头。
这样:
name :: Parser String
name = (:) <$> (satisfy isUpper) <*> (many $ satisfy isAlpha)
直到现在一切都很好,唯一的问题是我必须为类做类似的事情(数据,类型?!)人(*Main> parse name1 "hello"
Nothing
*Main> parse name1 "Hello"
Just "Hello"
)
所以,我有这个:
data Person
然后,在一行中,我必须为data Person = Person String deriving (Eq, Show)
编写解析器,但名称应该满足函数Person
,这意味着,名称应该只是一个文字字符串,第一个是大写的。
它应该有效:
name
其中:
> parse parserPerson "Chuck"
Just (Person "Chuck")
> parse parserPerson "chuck"
Nothing
正如你所看到的,bevor“Chuck”有parserPerson :: Parser Person
parserPerson = ???
,所以我不得不以某种方式使用Person
来获取它。
就是这样,只有一行*>
,<$>
和<*>
就行了。
我没有线索,我对此感到疯狂。也许有人可以帮助我。
修改
*>
和satisfy :: (Char -> Bool) -> Parser Char -- parse a desired character
satisfy p = Parser check
where
check (c:s) | p c = [(c,s)] -- successful
check _ = [ ] -- no parse
(many
)是来自some
Control.Applicative
答案 0 :(得分:1)
正如tsorn所说,答案非常简单......
parserPerson :: Parser Person
parserPerson = Person <$> name1
它起作用,因为定义了Functor Instacnce。
instance Functor Parser where
fmap f (Parser p) = Parser $ \s -> map (\(a,b) -> (f a, b)) $ p s