4

它来自另一个问题,但情况发生了变化。

Parsec 函数“parse”和“Stream”类的类型签名

我现在想知道如何import使事情变得不同。


文件:RunParse.hs

module RunParse where
import System.IO
import Data.Functor.Identity (Identity)
----import Text.Parsec ()     ....................(1)
----import Text.Parsec        ....................(2)
import Text.Parsec.Prim (Parsec, parse, Stream)

runIOParse :: (Show a) => Parsec String () a -> String -> IO ()
runIOParse pa fn =
  do
    inh <- openFile fn ReadMode
    outh <- openFile (fn ++ ".parseout") WriteMode
    instr <- hGetContents inh
    let result = case parse pa fn instr of
                   Right rs -> show rs
                   Left err -> "error"
    hPutStr outh result
    hClose inh
    hClose outh

(我使用的是 ghc 7.0.4)

将文件加载到 ghci 中:

> :l RunParse.hs

它告诉我:


RunParse.hs:13:23:
Could not deduce (Stream String Identity t0)
  arising from a use of `parse'
from the context (Show a)
  bound by the type signature for
             runIOParse :: Show a => Parsec String () a -> String -> IO ()
  at RunParse.hs:(8,1)-(18,15)
Possible fix:
  add (Stream String Identity t0) to the context of
    the type signature for
      runIOParse :: Show a => Parsec String () a -> String -> IO ()
  or add an instance declaration for (Stream String Identity t0)
In the expression: parse pa fn instr
In the expression:
  case parse pa fn instr of {
    Right rs -> show rs
    Left err -> "error" }
In an equation for `result':
    result
      = case parse pa fn instr of {
          Right rs -> show rs
          Left err -> "error" }

然后我添加了(1)或(2):

import Text.Parsec ()     ....................(1)
import Text.Parsec        ....................(2)

然后:l RunParse,加载成功。

然后我删除所有(1)和(2),然后:l RunParse,仍然成功!

然后我:q退出了ghci,重启了ghci,和启动一样,加载失败。

这是 ghc 的错误,还是我应该了解更多import

PS RunParse.hs 在ghc -c --make RunParse.hs没有 (1) 和 (2) 的情况下失败了。

4

1 回答 1

5

错误消息告诉您编译器找不到Stream String Identity t0. 此实例定义在Text.Parsec.String

instance (Monad m) => Stream [tok] m tok where
    uncons []     = return $ Nothing
    uncons (t:ts) = return $ Just (t,ts)

导入Text.ParsecStream实例从Text.Parsec.String范围内引入并使您的代码编译。更改import Text.Parsec()为 justimport Text.Parsec.String()也将修复此错误。

重新启动 GHCi 后无法加载代码的问题是一个已知问题。GHCi 在控制实例声明的范围方面做得不是很好。因此,一旦您加载了一个模块,来自它的实例声明将在会话的其余部分保持在范围内。import Text.Parsec ()这就是为什么 GHCi 在您删除线路后没有抱怨的原因。

于 2011-06-17T06:50:24.070 回答