<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Even ‘better’ </div><div class=""><div style="color: rgb(248, 248, 242); background-color: rgb(39, 40, 34); font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 20px; line-height: 30px; white-space: pre;" class=""><div class=""><span style="color: #f92672;" class="">instance</span> <span style="color: #66d9ef;font-style: italic;" class="">Monad</span> m <span style="color: #f92672;" class="">=></span> <span style="color: #66d9ef;font-style: italic;" class="">Functor</span> (<span style="color: #66d9ef;font-style: italic;" class="">EitherT</span> m a) <span style="color: #f92672;" class="">where</span></div><div class="">    fmap f m <span style="color: #f92672;" class="">=</span> <span style="color: #ae81ff;" class="">EitherT</span> <span style="color: #f92672;" class="">$</span> runEitherT m <span style="color: #f92672;" class="">>>=</span> <span style="color: #f92672;" class="">\</span>mv <span style="color: #f92672;" class="">-></span> return <span style="color: #f92672;" class="">$</span> fmap f mv</div><div class=""></div></div></div><div class=""><br class=""></div><div class="">:)</div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On 12 Apr 2018, at 21:32, mike h <<a href="mailto:mike_k_houghton@yahoo.co.uk" class="">mike_k_houghton@yahoo.co.uk</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><span class=""><span class=""><div class=""><div style="color: rgb(248, 248, 242); background-color: rgb(39, 40, 34); font-family: Menlo, Monaco, 'Courier New', monospace; font-size: 20px; line-height: 30px; white-space: pre;" class=""><div class=""><span style="color: #f92672;" class="">instance</span> <span style="color: #66d9ef;font-style: italic;" class="">Monad</span> m <span style="color: #f92672;" class="">=></span> <span style="color: #66d9ef;font-style: italic;" class="">Functor</span> (<span style="color: #66d9ef;font-style: italic;" class="">EitherT</span> m a) <span style="color: #f92672;" class="">where</span></div><div class="">   fmap f m <span style="color: #f92672;" class="">=</span> <span style="color: #ae81ff;" class="">EitherT</span> <span style="color: #f92672;" class="">$</span> <span style="color: #f92672;" class="">do</span></div><div class="">       mv <span style="color: #f92672;" class=""><-</span> runEitherT m</div><div class="">       <span style="color: #f92672;" class="">case</span> mv <span class="">of</span></div><span class="">           Left  lv -> return $ Left lv<br class=""></span><div class="">           <span style="color: #ae81ff;" class="">Right</span> rv <span style="color: #f92672;" class="">-></span> return <span style="color: #f92672;" class="">$</span> <span style="color: #ae81ff;" class="">Right</span> (f rv)</div><br class=""></div></div></span></span><span class=""><div class=""><br class=""></div><div class="">Thanks all :) I think its correct. The compiler does! </div><div class="">Mike</div><div class=""><br class=""></div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 12 Apr 2018, at 17:27, David McBride <<a href="mailto:toad3k@gmail.com" class="">toad3k@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class=""><div class=""><span class="gmail-im">You will feel like this was obvious in hindsight.<br class=""><br class="">fmap :: (a -> b) -> f a -> f b<br class=""></span></div><span class="gmail-im">fmap (a -> b) -> EitherT m c a -> EitherT m c b<br class=""></span><span class="gmail-im"><br class=""></span></div><div class=""><span class="gmail-im">Now follow the types in your code.<br class=""></span></div><div class=""><span class="gmail-im">m :: EitherT m c a<br class=""></span></div><div class=""><span class="gmail-im">mv :: Either c a<br class=""></span></div><div class=""><span class="gmail-im">return mv :: EitherT m c a -- <- you are back to the wrong type.<br class=""><br class=""></span></div><div class=""><span class="gmail-im">How can you instead return EitherT m c b?<br class=""></span></div><div class=""><span class="gmail-im"></span></div><div class=""><span class="gmail-im"><br class=""></span></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Thu, Apr 12, 2018 at 6:25 AM, mike h <span dir="ltr" class=""><<a href="mailto:mike_k_houghton@yahoo.co.uk" target="_blank" class="">mike_k_houghton@yahoo.co.uk</a>></span> wrote:<br class=""><blockquote style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex" class="gmail_quote">Hi,<br class="">
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 class="">
<br class="">
<br class="">
This is what I have<br class="">
<br class="">
newtype EitherT m a b = EitherT {runEitherT :: m (Either a b)}<br class="">
instance Monad m => Functor (EitherT m a) where<br class="">
    ---- fmap :: (a -> b) -> f a -> f b<br class="">
    fmap f m = EitherT $ do<br class="">
        mv <- runEitherT m<br class="">
        case mv of<br class="">
            Left _   -> return mv<br class="">
            Right rv -> return $ Right (f rv)<br class="">
<br class="">
<br class="">
<br class="">
and here is the compilers view<br class="">
Phrase.hs:31:25: error:<br class="">
    • Couldn't match type ‘b’ with ‘a1’<br class="">
      ‘b’ is a rigid type variable bound by<br class="">
        the type signature for:<br class="">
          fmap :: forall a1 b. (a1 -> b) -> EitherT m a a1 -> EitherT m a b<br class="">
        at Phrase.hs:27:5-8<br class="">
      ‘a1’ is a rigid type variable bound by<br class="">
        the type signature for:<br class="">
          fmap :: forall a1 b. (a1 -> b) -> EitherT m a a1 -> EitherT m a b<br class="">
        at Phrase.hs:27:5-8<br class="">
      Expected type: m (Either a a1)<br class="">
        Actual type: m (Either a b)<br class="">
    • In the expression: return $ Right (f rv)<br class="">
      In a case alternative: Right rv -> return $ Right (f rv)<br class="">
      In a stmt of a 'do' block:<br class="">
        case mv of<br class="">
          Left _ -> return mv<br class="">
          Right rv -> return $ Right (f rv)<br class="">
    • Relevant bindings include<br class="">
        rv :: a1 (bound at Phrase.hs:31:19)<br class="">
        mv :: Either a a1 (bound at Phrase.hs:28:9)<br class="">
        m :: EitherT m a a1 (bound at Phrase.hs:27:12)<br class="">
        f :: a1 -> b (bound at Phrase.hs:27:10)<br class="">
        fmap :: (a1 -> b) -> EitherT m a a1 -> EitherT m a b<br class="">
          (bound at Phrase.hs:27:5)<br class="">
<br class="">
<br class="">
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 class="">
<br class="">
these lines from the compiler are particularly confusing<br class="">
      Expected type: m (Either a a1)<br class="">
        Actual type: m (Either a b)<br class="">
<br class="">
as I believe f is    f:: a1->b<br class="">
<br class="">
So just hints please and I expect I’ll have another duh moment.<br class="">
<br class="">
Thanks<br class="">
<br class="">
Mike<br class="">
<br class="">
<br class="">
<br class="">
______________________________<wbr class="">_________________<br class="">
Beginners mailing list<br class="">
<a href="mailto:Beginners@haskell.org" class="">Beginners@haskell.org</a><br class="">
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" rel="noreferrer" target="_blank" class="">http://mail.haskell.org/cgi-<wbr class="">bin/mailman/listinfo/beginners</a><br class="">
</blockquote></div><br class=""></div>
_______________________________________________<br class="">Beginners mailing list<br class=""><a href="mailto:Beginners@haskell.org" class="">Beginners@haskell.org</a><br class=""><a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" class="">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br class=""></div></blockquote></div><br class=""></div></span></div></div></blockquote></div><br class=""></body></html>