Search code examples
haskellliterate-programming

No instance for (GHC.Base.Alternative Parser) error running Literate Haskell code


I'm trying to execute examples in Graham Hutton's Programming in Haskell book (http://www.cs.nott.ac.uk/~gmh/book.html). Even though the examples are in literate haskell, I could launch ghci to load the examples; for example ghci cipher.lhs (http://www.cs.nott.ac.uk/~gmh/cipher.lhs):

GHCi, version 7.10.2: http://www.haskell.org/ghc/  :? for help
[1 of 1] Compiling Main             ( cipher.lhs, interpreted )
Ok, modules loaded: Main.
*Main> let2int 'a'
0

However with some examples, because of the changes in ghci, I have some issues; for example in Parsing.ls in chapter 8, I have No instance for (Applicative ...) error.

From https://ghc.haskell.org/trac/ghc/wiki/Migration/7.10 I got hints to remove some of the errors by adding some code.

> instance Applicative Parser where
>    pure  = return
>    (<*>) = ap  -- defined in Control.Monad
>
> instance Functor Parser where
>    fmap  = liftM
>
> instance Alternative Parser where
>     (<|>) = mplus
>     empty = mzero 

However, I couldn't resolve this error message:

Not in scope: type constructor or class ‘Alternative’

What's wrong with this, and how to solve this issue? The original code that causes the problem is from: http://www.cs.nott.ac.uk/~gmh/Parsing.lhs

Solution

Adding this code works fine:

import qualified Control.Applicative as CA
instance CA.Alternative Parser where ...

Solution

  • Right from the Link you posted:

    GHC says No instance for (Alternative ...)

    A side-effect of the AMP is that Alternative became a super-class of MonadPlus. The easy remedy:

    instance Alternative Foo where (<|>) = mplus empty = mzero

    so here it should be:

    import Control.Applicative
    
    instance Alternative Parser where
        (<|>) = mplus
        empty = mzero
    

    sadly I cannot tell you exactly if this will do because the links to the books code you did provide don't include the instance for MonadPlus

    where do find missing definitions

    the easiest way is to use hoogle or hayoo - as you can see in the link Hoogle for example will tell you that's in the base package and the Control.Applicative namespace

    dealing with the multiples

    Ok my bad again - you should be fine with

    import Control.Applicative (Alternative())
    

    or

    import qualified Control.Applicative as CA
    
    instance CA.Alternative Parser where ...
    

    or by qualifying all the stuff (like using Parsing.many instead of just many)

    again sorry that I cannot give you a 100% waterproof compiling solution - you might have to test a bit (for example I am not 100% sure about the () here import Control.Applicative (Alternative()) and you can probably strip it.