I'd like to parse some very simple text for example,
"abcxyzzzz\nhello\n" into ["abcxyzzz", "hello"] :: String.
Not looking for a simpler function to do this (like words) as I need to parse something more complex and I'm just laying the foundations here.
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
module RgParse where
import Data.Text (Text)
import Text.Megaparsec
import Text.Megaparsec.Char
data SimpleData = SimpleData String deriving (Eq, Show, Ord)
data SimpleData' = SimpleData' [String] deriving (Eq, Show, Ord)
instance ShowErrorComponent SimpleData where
showErrorComponent = show
instance ShowErrorComponent String where
showErrorComponent = show
simple :: Parsec String Text SimpleData
simple = do
x <- many (noneOf (Just '\n'))
pure $ SimpleData x
simple' :: Parsec String Text SimpleData'
simple' = do
x <- many (many (noneOf (Just '\n')))
pure $ SimpleData' x
example2 :: Text
example2 = "abcxyzzzz\nhello\n"
main :: IO ()
main = do
print "Simple:"
case parse simple "<stdin>" example2 of
Left bundle -> putStr (errorBundlePretty bundle)
Right result -> print result
print "Simple':"
case parse simple' "<stdin>" example2 of
Left bundle -> putStr (errorBundlePretty bundle)
Right result -> print result
print "done.."
The above unfortunately runs into an infinite loop / space leak upon entering simple' as it outputs the following:
Hello, Haskell!
[]
"Simple:"
SimpleData "abcxyzzzz"
"Simple':"
Using megaparsec-7.0.5 (not the latest 9.x.x).
Is there possibly a simpler approach to getting multiple lines?
Apply
manyonly to a parser that either consumes at least one token (here, oneChar) or fails. That's becausemanyworks by running its argument until it fails.many xmay consume zero tokens, somany (many x)breaks this requirement.Note that a line should at least involve a terminating newline. That allows that requirement to be fulfilled.
A looser requirement for
many pis that any repetition ofpmust fail after a finite number of iterations (and herep = many xnever fails), sopmight consume nothing in some steps, but then it must be stateful so that after some repetitions it eventually consumes something or fails. But the above approximation is a pretty good rule of thumb in practice.