I wrote a small parser with megaparsec:
module App (main) where
import Control.Monad (void)
import Text.Megaparsec
import Text.Megaparsec.String
import qualified Text.Megaparsec.Lexer as L
sc :: Parser ()
sc = L.space (void spaceChar) lineCmnt blockCmnt
where lineCmnt = L.skipLineComment "//"
blockCmnt = L.skipBlockComment "/*" "*/"
symbol :: String -> Parser String
symbol = L.symbol sc
semiParser :: Parser String
semiParser = symbol ";"
main :: IO()
main = do
input <- getLine
case parse semiParser input of
Left val -> putStrLn $ "Failed! "
Right val -> putStrLn $ "Passed! "
print "Done"
where sc
and symbol and semiParser
are from the tutorials. Now I would like to work with my result but I get a type error:
App.hs:23:5: error:
• Couldn't match expected type ‘String
-> Either (ParseError (Token String) Dec) String’
with actual type ‘Either t0 t1’
• In the pattern: Left val
In a case alternative: Left val -> putStrLn $ "Failed! "
In a stmt of a 'do' block:
case parse semiParser input of {
Left val -> putStrLn $ "Failed! "
Right val -> putStrLn $ "Passed! " }
App.hs:24:5: error:
• Couldn't match expected type ‘String
-> Either (ParseError (Token String) Dec) String’
with actual type ‘Either t2 t3’
• In the pattern: Right val
In a case alternative: Right val -> putStrLn $ "Passed! "
In a stmt of a 'do' block:
case parse semiParser input of {
Left val -> putStrLn $ "Failed! "
Right val -> putStrLn $ "Passed! " }
So, my question is: how do I match against String -> Either (ParseError (Token String) Dec) String
and get the error message or the result, if parsing failed?
I guess that the general form of this question is: How does pattern matching work? And I am confused in general how I can bind the result of a monad (such as Either
in another monad, such as IO
(I guess I have to pattern match and then lift the value into the context of the monad).