4

it came from another question, but things has changed.

The type signature of Parsec function 'parse' and the class 'Stream'

I'm now wondering what does import do to make things different.


file: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

(I'm using ghc 7.0.4)

load the file into ghci:

> :l RunParse.hs

it tells me:


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" }

then I added either (1) or (2):

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

Then :l RunParse , load succeeded.

Then I remove all of (1) and (2), then :l RunParse, still succeeded!

Then I :q quit the ghci, restart ghci, just same as the start, it failed to load.

Does this is a bug of ghc, or I should know more about import?

P.S. RunParse.hs failed the ghc -c --make RunParse.hs without (1) and (2).

3
  • 4
    "Then I remove all of (1) and (2), then :l RunParse, still succeeded!" Regarding this part, when you loaded the file the first time and imported Text.Parsec, its functions remained in scope when you reloaded the modified file. Then when you quit and restarted ghci, you returned to the Prelude, where Stream is undeclared. Commented Jun 17, 2011 at 7:19
  • Have you read through learnyouahaskell.com ? It covers a lot of this. Commented Jun 17, 2011 at 14:15
  • @Alex:I read it last year, But I forgot this. maybe because it not usually happens. Commented Jun 18, 2011 at 9:43

1 Answer 1

5

The error message tells you that the compiler can't find an instance declaration for Stream String Identity t0. This instance is defined in Text.Parsec.String:

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

Importing Text.Parsec brings the Stream instance from Text.Parsec.String in scope and makes your code compile. Changing import Text.Parsec() to just import Text.Parsec.String() will also fix this error.

Your problem with code not loading after restarting GHCi is a known issue. GHCi doesn't do a very good job of controlling the scope of instance declarations. So after you have loaded a module once, instance declarations from it stay in scope for the rest of the session. That's why GHCi didn't complain after you removed the import Text.Parsec () line.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.