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

发布于 2024-11-16 09:04:30 字数 2320 浏览 3 评论 0原文

它来自另一个问题,但事情已经改变了。

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,还是成功了!

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

这是 ghc 的错误,还是我应该了解更多关于 import 的信息?

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

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

甜柠檬 2024-11-23 09:04:30

该错误消息告诉您编译器找不到 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 会从 Text.Parsec.String< 引入 Stream 实例/code> 在范围内并使您的代码编译。将 import Text.Parsec() 更改为 import Text.Parsec.String() 也将修复此错误。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文