4

それは別の質問から来ましたが、状況は変わりました。

Parsec関数'parse'とクラス'Stream'の型シグネチャ

私は今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も、成功しました。

次に、ghciを:q終了し、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()justに変更するimport Text.Parsec.String()と、このエラーも修正されます。

GHCiを再起動した後にコードがロードされないという問題は、既知の問題です。GHCiは、インスタンス宣言のスコープを制御するという非常に優れた仕事をしていません。したがって、モジュールを一度ロードした後、そのモジュールからのインスタンス宣言は、セッションの残りの間スコープ内にとどまります。そのため、import Text.Parsec ()回線を削除した後、GHCiは文句を言いませんでした。

于 2011-06-17T06:50:24.070 に答える