[英]Parsec and liftIO, compilation error
I'm parsing a language and I want to have syntax to $include
other files while parsing. 我正在解析一种语言,并且想在解析时使用$include
其他文件的语法。
My code: 我的代码:
import Text.ParserCombinators.Parsec
import Text.Parsec.Prim (parserZero)
import Text.ParserCombinators.Parsec.Char
import Control.Monad.Trans
import Data.Functor.Identity
notaInclude :: Parser [SourcesItem]
notaInclude = do
try $ string "$Include" >> blanks1
char '"'
fileName <- quotedStringParser
char '"'
i <- getInput
included <- liftIO $ readFile fileName
setInput included
si <- sources
setInput i
return si
The error message from GHC: 来自GHC的错误消息:
Lazi/Lazi'nh/Language/Sources/Parser.hs:65:17:
No instance for (MonadIO Identity) arising from a use of `liftIO'
Possible fix: add an instance declaration for (MonadIO Identity)
In the expression: liftIO
In a stmt of a 'do' block: included <- liftIO $ readFile fileName
In the expression:
do { try
(do { string "$Include";
blanks1 });
char '"';
fileName <- quotedStringParser;
char '"';
.... }
How can I make it work? 我该如何运作?
IMO the parsing stage is not the right place to import files. IMO解析阶段不是导入文件的正确位置。 I suggest you parse the file as a whole and process the result after you are done. 我建议您将文件整体解析,并在完成后处理结果。
If you want to process the $include
directives while parsing, you'll need to run over IO
. 如果要在解析时处理$include
指令,则需要在IO
上运行。 Parsec exposes a monad transformer for this purpose called ParsecT
; 为此,Parsec公开了一个名为ParsecT
的monad转换ParsecT
; if you change the type of notaInclude
to ParsecT String () IO [SourceItem]
it should work. 如果将ParsecT String () IO [SourceItem]
的类型notaInclude
为ParsecT String () IO [SourceItem]
它应该可以工作。
However, in general I would side with @soupi's suggestion , and keep parsing pure and resolve $include
s after parsing. 但是,总的来说,我会支持@soupi的建议 ,并保持纯解析并在解析后解析$include
。 But maybe you have some good reason to do it this way for your particular application. 但是也许您有充分的理由针对您的特定应用程序执行此操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.