我正在学习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.String
为RegexLike Regex String
和RegexMaker Regex CompOption ExecOption String
提供了实例,因此它应该有效。另一方面,我可以看到错误消息中的regex
是类型变量,而不是具体类型,所以,也许不是......无论如何,这是我被卡住的地方。
可能存在解决no instance for
类型问题的常见模式吗?或者,在Haskell术语中,SmartGuess
的{{1}}类型类的实例?
答案 0 :(得分:3)
你在图书馆的一角,我的眼睛很黑。但是我在您的错误消息中注意到编译器说regex
您说的是Regex
。你的代码太多态了,所以几乎可以肯定你在某个地方有无限制,或者你把错误的参数传递给了某些东西(而忽略了一个随后变成多态的参数)。
类型级地狱并不好玩,但如果您将regex
的类型签名放入where
子句,我认为您可能会收到更多信息性错误消息。我无法弄清楚它应该是什么类型,但如果你知道,这可能会将实例问题解决为一种更容易处理的类型错误。
我讨厌类型级的地狱。