65

I am trying to define a new monad and I am getting a strange error

newmonad.hs

newtype Wrapped a = Wrap {unwrap :: a}
instance Monad Wrapped where
 (>>=) (Wrap x) f = f x
 return x = Wrap x
main = do
 putStrLn "yay"
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.10.1
$ ghc newmonad.hs 
[1 of 1] Compiling Main ( newmonad.hs, newmonad.o )
newmonad.hs:2:10:
 No instance for (Applicative Wrapped)
 arising from the superclasses of an instance declaration
 In the instance declaration for ‘Monad Wrapped’

Why do I need to define an instance of Applicative?

recursion.ninja
5,4888 gold badges50 silver badges81 bronze badges
asked Jul 27, 2015 at 11:57
1
  • 3
    By the way, you might want to get used to use a capital letter for the first letter in your Haskell source files name. This is because file names should match module names which do start with a capital letter. It doesn't matter much for scripting such as in your case, of course. Best of luck! Commented Jul 28, 2015 at 15:46

2 Answers 2

97

This is the Applicative Monad Proposal (AMP). Now whenever you declare something as Monad, you also have to declare it as Applicative (and therefore Functor). Mathematically speaking, every monad is an applicative functor, so this makes sense.

You can do the following to remove the error:

instance Functor Wrap where
 fmap f (Wrap x) = Wrap (f x)
instance Applicative Wrap where
 pure = Wrap
 Wrap f <*> Wrap x = Wrap (f x)

https://wiki.haskell.org/Functor-Applicative-Monad_Proposal

Edit: Maybe I should point out more clearly that this is a recent thing? The code you posted used to work before, but with recent versions of GHC you'll get an error. It's a breaking change.

Edit: The following declarations should work for any monad:

import Control.Applicative -- Otherwise you can't do the Applicative instance.
import Control.Monad (liftM, ap)
instance Functor ??? where
 fmap = liftM
instance Applicative ??? where
 pure = return
 (<*>) = ap

Depending on the monad in question, there may be more efficient implementations possible, but this is a simple starting point.

answered Jul 27, 2015 at 12:02
Sign up to request clarification or add additional context in comments.

14 Comments

Monads let you do things that are impossible with plain Applicative alone. In particular, choosing which action to run next based on the result of the previous action.
Specifically, the recent version of GHC at which this becomes an error is version 7.10.
Functors are more generic than Applicatives, and Applicatives are more generic than Monads. Powerfulness (i.e. the number of different operations you can perform on them) works the other way round.
This probably will be a frequent question for a while for people using new GHC with old tutorials etc. To make this answer more useful for others coming upon it, maybe you could give an Applicative/Functor definition that works generically for all Monads? (E.g. using do notation, or liftM and ap (although those require an import.))
The migration guide at ghc.haskell.org/trac/ghc/wiki/Migration/7.10 says "DO NOT USE pure = return". (I have no idea what any of this means at this point, I am simply pointing out something that the guide is saying)
|
2

The most normalized and unobtrusive answer is :-

as Monad is dependent upon Applicative

class Applicative m => Monad m where ...

and Applicative is dependent upon Functor

class Functor f => Applicative f where ...

we need the instance definitions

> instance Functor Wrapped where
> fmap = liftM

and

> instance Applicative Wrapped where
> pure = return
> (<*>) = ap
answered Jul 10, 2018 at 17:22

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.