Even ‘better’ 
instance Monad m => Functor (EitherT m a) where
fmap f m = EitherT $ runEitherT m >>= \mv -> return $ fmap f mv

:)


On 12 Apr 2018, at 21:32, mike h <mike_k_houghton@yahoo.co.uk> wrote:

instance Monad m => Functor (EitherT m a) where
fmap f m = EitherT $ do
mv <- runEitherT m
case mv of
Left lv -> return $ Left lv
Right rv -> return $ Right (f rv)


Thanks all :) I think its correct. The compiler does! 
Mike


On 12 Apr 2018, at 17:27, David McBride <toad3k@gmail.com> wrote:

You will feel like this was obvious in hindsight.

fmap :: (a -> b) -> f a -> f b
fmap (a -> b) -> EitherT m c a -> EitherT m c b

Now follow the types in your code.
m :: EitherT m c a
mv :: Either c a
return mv :: EitherT m c a -- <- you are back to the wrong type.

How can you instead return EitherT m c b?


On Thu, Apr 12, 2018 at 6:25 AM, mike h <mike_k_houghton@yahoo.co.uk> wrote:
Hi,
I’m trying to write EitherT from first principles and I’m stuck at the first hurdle - Functor.  I’m looking for a hint rather than a complete answer :)


This is what I have

newtype EitherT m a b = EitherT {runEitherT :: m (Either a b)}
instance Monad m => Functor (EitherT m a) where
    ---- fmap :: (a -> b) -> f a -> f b
    fmap f m = EitherT $ do
        mv <- runEitherT m
        case mv of
            Left _   -> return mv
            Right rv -> return $ Right (f rv)



and here is the compilers view
Phrase.hs:31:25: error:
    • Couldn't match type ‘b’ with ‘a1’
      ‘b’ is a rigid type variable bound by
        the type signature for:
          fmap :: forall a1 b. (a1 -> b) -> EitherT m a a1 -> EitherT m a b
        at Phrase.hs:27:5-8
      ‘a1’ is a rigid type variable bound by
        the type signature for:
          fmap :: forall a1 b. (a1 -> b) -> EitherT m a a1 -> EitherT m a b
        at Phrase.hs:27:5-8
      Expected type: m (Either a a1)
        Actual type: m (Either a b)
    • In the expression: return $ Right (f rv)
      In a case alternative: Right rv -> return $ Right (f rv)
      In a stmt of a 'do' block:
        case mv of
          Left _ -> return mv
          Right rv -> return $ Right (f rv)
    • Relevant bindings include
        rv :: a1 (bound at Phrase.hs:31:19)
        mv :: Either a a1 (bound at Phrase.hs:28:9)
        m :: EitherT m a a1 (bound at Phrase.hs:27:12)
        f :: a1 -> b (bound at Phrase.hs:27:10)
        fmap :: (a1 -> b) -> EitherT m a a1 -> EitherT m a b
          (bound at Phrase.hs:27:5)


what I think I need to do is fmap over the right value after pulling if out of the monad m by doing   mv <- runEitherT m

these lines from the compiler are particularly confusing
      Expected type: m (Either a a1)
        Actual type: m (Either a b)

as I believe f is    f:: a1->b

So just hints please and I expect I’ll have another duh moment.

Thanks

Mike



_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners