<div dir="ltr"><div><div><span class="gmail-im">You will feel like this was obvious in hindsight.<br><br>fmap :: (a -> b) -> f a -> f b<br></span></div><span class="gmail-im">fmap (a -> b) -> EitherT m c a -> EitherT m c b<br></span><span class="gmail-im"><br></span></div><div><span class="gmail-im">Now follow the types in your code.<br></span></div><div><span class="gmail-im">m :: EitherT m c a<br></span></div><div><span class="gmail-im">mv :: Either c a<br></span></div><div><span class="gmail-im">return mv :: EitherT m c a -- <- you are back to the wrong type.<br><br></span></div><div><span class="gmail-im">How can you instead return EitherT m c b?<br></span></div><div><span class="gmail-im"></span></div><div><span class="gmail-im"><br></span></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Apr 12, 2018 at 6:25 AM, mike h <span dir="ltr"><<a href="mailto:mike_k_houghton@yahoo.co.uk" target="_blank">mike_k_houghton@yahoo.co.uk</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
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 :)<br>
<br>
<br>
This is what I have<br>
<br>
newtype EitherT m a b = EitherT {runEitherT :: m (Either a b)}<br>
instance Monad m => Functor (EitherT m a) where<br>
    ---- fmap :: (a -> b) -> f a -> f b<br>
    fmap f m = EitherT $ do<br>
        mv <- runEitherT m<br>
        case mv of<br>
            Left _   -> return mv<br>
            Right rv -> return $ Right (f rv)<br>
<br>
<br>
<br>
and here is the compilers view<br>
Phrase.hs:31:25: error:<br>
    • Couldn't match type ‘b’ with ‘a1’<br>
      ‘b’ is a rigid type variable bound by<br>
        the type signature for:<br>
          fmap :: forall a1 b. (a1 -> b) -> EitherT m a a1 -> EitherT m a b<br>
        at Phrase.hs:27:5-8<br>
      ‘a1’ is a rigid type variable bound by<br>
        the type signature for:<br>
          fmap :: forall a1 b. (a1 -> b) -> EitherT m a a1 -> EitherT m a b<br>
        at Phrase.hs:27:5-8<br>
      Expected type: m (Either a a1)<br>
        Actual type: m (Either a b)<br>
    • In the expression: return $ Right (f rv)<br>
      In a case alternative: Right rv -> return $ Right (f rv)<br>
      In a stmt of a 'do' block:<br>
        case mv of<br>
          Left _ -> return mv<br>
          Right rv -> return $ Right (f rv)<br>
    • Relevant bindings include<br>
        rv :: a1 (bound at Phrase.hs:31:19)<br>
        mv :: Either a a1 (bound at Phrase.hs:28:9)<br>
        m :: EitherT m a a1 (bound at Phrase.hs:27:12)<br>
        f :: a1 -> b (bound at Phrase.hs:27:10)<br>
        fmap :: (a1 -> b) -> EitherT m a a1 -> EitherT m a b<br>
          (bound at Phrase.hs:27:5)<br>
<br>
<br>
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<br>
<br>
these lines from the compiler are particularly confusing<br>
      Expected type: m (Either a a1)<br>
        Actual type: m (Either a b)<br>
<br>
as I believe f is    f:: a1->b<br>
<br>
So just hints please and I expect I’ll have another duh moment.<br>
<br>
Thanks<br>
<br>
Mike<br>
<br>
<br>
<br>
______________________________<wbr>_________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/beginners</a><br>
</blockquote></div><br></div>