首页 文章

哈斯克尔:如何度过'no instance for'?

提问于
浏览
2

我正在学习Haskell . 我在this book的第8章 . 到目前为止我学到的主要内容是Haskell对我非常不友好,它尽可能地咬我的屁股 . 而且......哎呀!足够的哀悼,对企业 .

这是代码:

module GlobRegex (
  globToRegex,
  matchesGlob
) where

import Text.Regex.Posix
import Text.Regex.Posix.String
import Text.Regex.Base.RegexLike

data CaseOpt = Case | NoCase
  deriving (Eq)

matchesGlob :: String -> String -> CaseOpt -> Bool
matchesGlob name pat caseopt = match regex name where
  regex = case caseopt of
               NoCase -> makeRegexOpts (defaultCompOpt + compIgnoreCase) defaultExecOpt (globToRegex pat)
               Case -> makeRegex (globToRegex pat)

globToRegex :: String -> String
...

以下是编译失败的原因:

Prelude Text.Regex.Posix Text.Regex.Base.RegexLike> :load globtoregex\GlobRegex.
hs
[1 of 1] Compiling GlobRegex        ( globtoregex\GlobRegex.hs, interpreted )

globtoregex\GlobRegex.hs:14:31:
    No instance for (RegexLike regex [Char])
      arising from a use of `match' at globtoregex\GlobRegex.hs:14:31-46
    Possible fix:
      add an instance declaration for (RegexLike regex [Char])
    In the expression: match regex name
    In the definition of `matchesGlob':
        matchesGlob name pat caseopt
                      = match regex name
                      where
                          regex = case caseopt of {
                                    NoCase
                                      -> makeRegexOpts
                                           (defaultCompOpt + compIgnoreCase)
                                           defaultExecOpt
                                           (globToRegex pat)
                                    Case -> makeRegex (globToRegex pat) }

globtoregex\GlobRegex.hs:17:23:
    No instance for (RegexMaker regex CompOption execOpt String)
      arising from a use of `makeRegex'
                   at globtoregex\GlobRegex.hs:17:23-49
    Possible fix:
      add an instance declaration for
      (RegexMaker regex CompOption execOpt String)
    In the expression: makeRegex (globToRegex pat)
    In a case alternative: Case -> makeRegex (globToRegex pat)
    In the expression:
        case caseopt of {
          NoCase
            -> makeRegexOpts
                 (defaultCompOpt + compIgnoreCase) defaultExecOpt (globToRegex p
at)
          Case -> makeRegex (globToRegex pat) }
Failed, modules loaded: none.

据我所知, Text.Regex.Posix.StringRegexLike Regex StringRegexMaker Regex CompOption ExecOption String 提供了实例,因此它应该可以工作 . 另一方面,我可以看到错误消息中的 regex 是类型变量,而不是具体类型,所以,也许不是......无论如何,这是我被卡住的地方 .

可能有一个解决 no instance for 类型问题的常见模式?或者,在Haskell术语中, SmartGuess 的类型为 no instance for

1 回答

  • 3

    你在图书馆的一角,我的眼睛很黑 . 但是我在你的错误信息中注意到编译器说 regex 你说的是 Regex . 你的代码太多态了,所以几乎可以肯定你在某个地方有无限制,或者你把错误的参数传递给了某些东西(而忽略了一个随后变成多态的参数) .

    类型级地狱并不好玩,但如果您将 regex 的类型签名放入 where 子句中,我认为您可能会收到更多信息性错误消息 . 我可以't make out what type it'应该是,但如果你知道,这可能会将实例问题解决为一种更容易处理的类型错误 .

    我讨厌类型级的地狱 .

相关问题