prosseek
prosseek

Reputation: 190859

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

Upvotes: 3

Views: 2055

Answers (2)

Alexander Myshov
Alexander Myshov

Reputation: 3101

I've also stumbled upon this issue. For those who want adapted version of the module parsing.lhs just place in import section:

> import qualified Control.Applicative as CA

and after type Parser definition this code:

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

Or take adapted version of the module here https://gist.github.com/myshov/85badeb087c51631aee3

Upvotes: 1

Random Dev
Random Dev

Reputation: 52280

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.

Upvotes: 5

Related Questions