<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>