我用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"
其中sc
和符号以及semiParser
来自教程。现在我想使用我的结果,但是我得到了一个类型错误:
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! " }
所以,我的问题是:如果解析失败,如何匹配String -> Either (ParseError (Token String) Dec) String
并获取错误消息或结果?
我想这个问题的一般形式是:模式匹配如何工作?我一般都很困惑如何绑定monad的结果(例如Either
在另一个monad中,例如IO
(我想我必须模式匹配然后将值提升到上下文中(monad)。
答案 0 :(得分:0)
parse :: Stream s Identity t => Parsec s () a -> SourceName -> s -> Either ParseError a
-- ^^^^^^^^^^ --
你忘记了这个论点。尝试
case parse semiParser "input name here" input of