缺少实例错误,模块加载和GHCi

时间:2011-06-17 06:16:11

标签: haskell import ghci

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

The type signature of Parsec function 'parse' and the class '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

P.S。 RunParse.hs使ghc -c --make RunParse.hs没有(1)和(2)失败。

1 个答案:

答案 0 :(得分: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.Parsec会在Stream范围内带来Text.Parsec.String实例并使代码编译。将import Text.Parsec()更改为仅import Text.Parsec.String()也可以解决此错误。

重启GHCi后代码未加载的问题是known issue。 GHCi在控制实例声明的范围方面做得不是很好。因此,在您加载模块一次之后,其中的实例声明将保留在会话的其余部分的范围内。这就是为什么GHCi在您删除import Text.Parsec ()行后没有抱怨的原因。