How do I get Parsec to let me call `read` :: Int?

前端 未结 3 1842
感情败类
感情败类 2020-12-21 15:50

I\'ve got the following, which type-checks:

p_int = liftA read (many (char \' \') *> many1 digit <* many (char \' \'))

Now, as the fu

3条回答
  •  攒了一身酷
    2020-12-21 16:24

    How do I get Parsec to let me call read :: Int?

    A second answer is "Don't use read".

    Using read is equivalent to re-parsing data you have already parsed - so using it within a Parsec parser is a code smell. Parsing natural numbers is harmless enough, but read has different failure semantics to Parsec and it is tailored to Haskell's lexical syntax so using it for more complicated number formats is problematic.

    If you don't want to go to the trouble of defining a LanguageDef and using Parsec's Token module here is a natural number parser that doesn't use read:

    -- | Needs @foldl'@ from Data.List and 
    -- @digitToInt@ from Data.Char.
    --
    positiveNatural :: Stream s m Char => ParsecT s u m Int
    positiveNatural = 
        foldl' (\a i -> a * 10 + digitToInt i) 0 <$> many1 digit
    

提交回复
热议问题