Haskell: how to get through 'no instance for' ?

Posted by artemave on Stack Overflow See other posts from Stack Overflow or by artemave
Published on 2010-03-20T18:21:55Z Indexed on 2010/03/20 18:31 UTC
Read the original article Hit count: 506

Filed under:

I am learning Haskell. I am on the 8th chapter of this book. The main thing I've learned so far is that Haskell is very unfriendly to me and it bites my ass where possible. Moreover... Heck! Enough mourning, to business.

Here is the code:

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

And here is how it fails to compile:

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.

To my best understanding, Text.Regex.Posix.String provides instances for RegexLike Regex String and RegexMaker Regex CompOption ExecOption String, so it should work. On the other hand, I can see that regex in the error message is type variable, not a concrete type, so, perhaps not... Anyway, this is where I am stuck.

May be there is a common pattern for resolving no instance for type of problems? Or, in Haskell terms, instance of SmartGuess typeclass for no instance for?

© Stack Overflow or respective owner

Related posts about haskell