Отсутствующие ошибки экземпляра, загрузка модуля и GHCi - PullRequest
4 голосов
/ 17 июня 2011

оно пришло из другого вопроса, но все изменилось.

Сигнатура типа функции Parsec 'parse' и класса 'Stream'

I'mТеперь интересно, что делает import, чтобы сделать вещи по-другому.


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

(я использую 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).

1 Ответ

5 голосов
/ 17 июня 2011

Сообщение об ошибке говорит вам, что компилятор не может найти объявление экземпляра для 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, является известной проблемой . GHCi не очень хорошо контролирует объем объявлений экземпляров. Поэтому после того, как вы загрузили модуль один раз, объявления экземпляра из него остаются в области действия до конца сеанса. Вот почему GHCi не жаловался после того, как вы удалили строку import Text.Parsec ().

...