如何匹配 megaparsec 结果?
How to match megaparsec result?
我用 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
(我想我必须进行模式匹配,然后将值提升到上下文中单子的)。
parse :: Stream s Identity t => Parsec s () a -> SourceName -> s -> Either ParseError a
-- ^^^^^^^^^^ --
你忘了那个论点。尝试
case parse semiParser "input name here" input of
我用 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
(我想我必须进行模式匹配,然后将值提升到上下文中单子的)。
parse :: Stream s Identity t => Parsec s () a -> SourceName -> s -> Either ParseError a
-- ^^^^^^^^^^ --
你忘了那个论点。尝试
case parse semiParser "input name here" input of