Haskell:如何通过“无实例”?

我正在学习Haskell。 我在本书的第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 globtoregexGlobRegex.
hs
[1 of 1] Compiling GlobRegex        ( globtoregexGlobRegex.hs, interpreted )

globtoregexGlobRegex.hs:14:31:
    No instance for (RegexLike regex [Char])
      arising from a use of `match' at globtoregexGlobRegex.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) }

globtoregexGlobRegex.hs:17:23:
    No instance for (RegexMaker regex CompOption execOpt String)
      arising from a use of `makeRegex'
                   at globtoregexGlobRegex.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.String提供了RegexLike Regex StringRegexMaker Regex CompOption ExecOption String实例,所以它应该可以工作。 另一方面,我可以看到,错误消息中的regex是类型变量,而不是具体类型,所以也许不是......无论如何,这是我卡住的地方。

可能有no instance for解决问题类型的no instance for的常见模式? 或者,从Haskell的角度来看, SmartGuess类型类的no instance for吗?


你在图书馆的一个角落,我的眼睛很黑。 但我注意到在你的错误信息中,编译器说regex是你说的regex Regex 。 你的代码太多态了,所以几乎可以肯定你在某个地方有非终结符,或者你将错误的参数传递给了某个东西(并且忽略了一个变成多态的参数)。

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

我讨厌类型级的地狱。

链接地址: http://www.djcxy.com/p/43515.html

上一篇: Haskell: how to get through 'no instance for'?

下一篇: Make a typeclass instance automatically an instance of another