简体   繁体   English

Parsec和liftIO,编译错误

[英]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]的类型notaIncludeParsecT 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM