Haskell:如何通过“没有实例”?

时间:2010-03-20 18:21:55

标签: haskell typeclass

我正在学习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的{​​{1}}类型类的实例?

1 个答案:

答案 0 :(得分:3)

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

类型级地狱并不好玩,但如果您将regex的类型签名放入where子句,我认为您可能会收到更多信息性错误消息。我无法弄清楚它应该是什么类型,但如果你知道,这可能会将实例问题解决为一种更容易处理的类型错误。

我讨厌类型级的地狱。