views:

73

answers:

1

Why is it that I can do the following:

import Data.Word
import Data.Binary.Get
import Control.Applicative
import Control.Monad.Error

getW1 :: ErrorT String Get Word8
getW1 = lift getWord8

f1 = (+1) <$> getW1

but I cannot do:

f2 = (+) <$> getW1 <*> getW1

and how I do I modify f2 so that it will work as I intend?

+1  A: 

<$> only requires that ErrorT String Get to be an instance of Functor. <*> requires that it be an instance of Applicative. I think this instance declaration should work:

{-# LANGUAGE FlexibleInstances #-}

instance (Error e, Monad m) => Applicative (ErrorT e m) where
    pure = return
    (<*>) = ap
MtnViewMark
Makes me wonder: Why doesn't Applicative define instance (Monad m) => Applicative m? It only does so for "WrappedMonad m".
MtnViewMark
Ah, I see, it would require UndecidableInstances to do so.
MtnViewMark
Of course, adding this instance declaration will leave you with an orphan instance, unfortunately.
Steve