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?
-
3By 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!MasterMastic– MasterMastic2015年07月28日 15:46:19 +00:00Commented Jul 28, 2015 at 15:46
2 Answers 2
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.
14 Comments
Applicative/Functor definition that works generically for all Monads? (E.g. using do notation, or liftM and ap (although those require an import.))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)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