简体   繁体   English

为整数编写解析器-类型错误

[英]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 IntegerrunParser (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 -> bParser内部提供函数时Maybe (String, a)这里的aMaybe (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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM