[英]Writing Parser for Integer - Type Error
Given the following Parser
definitions (from Prof. Brent Yorgey's U of Penn class ): 鉴于以下
Parser
定义(自佩恩教授布伦特Yorgey鈥檚U 类 ):
newtype Parser a = Parser { runParser :: String -> Maybe (a, String) }
satisfy :: (Char -> Bool) -> Parser Char
satisfy p = Parser f
where
f [] = Nothing -- fail on the empty input
f (x:xs) -- check if x satisfies the predicate
-- if so, return x along with the remainder
-- of the input (that is, xs)
| p x = Just (x, xs)
| otherwise = Nothing -- otherwise, fail
Given the following parser for one or more of 'a'
: 给定以下
one or more of 'a'
解析器:
oneOrMore :: Parser a -> Parser [a]
oneOrMore p = (:) <$> p <*> (zeroOrMore p)
And, now I'd like to extract an Integer
or nothing: 而且,现在我想提取一个
Integer
或不提取任何内容:
parseInteger :: String -> Maybe Integer
parseInteger = fmap (read . fst) $ runParser (oneOrMore (satisfy isNumber))
But I'm getting this compile-time error: 但是我遇到了这个编译时错误:
JsonParser.hs:42:36:
Couldn't match type ‘(String, b0)’ with ‘Maybe ([Char], String)’
Expected type: String -> (String, b0)
Actual type: String -> Maybe ([Char], String)
In the second argument of ‘($)’, namely
‘runParser (oneOrMore (satisfy isNumber))’
In the expression:
fmap (read . fst) $ runParser (oneOrMore (satisfy isNumber))
Failed, modules loaded: SExpr, Model, AParser.
*SExpr Data.Char> :t runParser
runParser :: Parser a -> String -> Maybe (a, String)
I'm confused since runParser
has a type of String -> Maybe (a, String)
. 我很困惑,因为
runParser
具有runParser
String -> Maybe (a, String)
。
Calling fmap
on Maybe (a, String)
should apply fmap
's function to the (a, String)
type. 在
Maybe (a, String)
上调用fmap
应该将fmap
的函数应用于(a, String)
类型。
What am I missing? 我想念什么?
You need to use (.)
instead of $
: 您需要使用
(.)
而不是$
:
fmap (read . fst) . runParser (oneOrMore (satisfy isNumber))
alternatively you need to supply the string to runParser
: 或者,您需要将字符串提供给
runParser
:
parseInteger s = fmap (read . fst) $ runParser (oneOrMore (satisfy isNumber)) s
fmap (read . fst)
in this case has type Maybe (String, a) -> Maybe Integer
and runParser (oneOrMore (satisfy isNumber))
has type String -> Maybe (String, String)
. 在这种情况下,
fmap (read . fst)
类型为Maybe (String, a) -> Maybe Integer
而runParser (oneOrMore (satisfy isNumber))
类型为runParser (oneOrMore (satisfy isNumber))
String -> Maybe (String, String)
。 These two functions can be composed with (.)
, but ($)
has type (a -> b) -> a -> b
- here a
is Maybe (String, a)
while you are supplying the function inside the Parser
. 这两个函数可以用
(.)
组成,但是($)
类型为(a -> b) -> a -> b
在Parser
内部提供函数时Maybe (String, a)
这里的a
是Maybe (String, a)
。
If you apply the string to this function instead, you can get the Maybe (String, a)
required by ($)
. 如果将字符串应用于此函数,则可以获得
($)
所需的Maybe (String, a)
($)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.