[Haskell-beginners] EitherT

mike h mike_k_houghton at yahoo.co.uk
Fri Apr 13 08:35:01 UTC 2018


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 at 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 at gmail.com <mailto:toad3k at 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 at yahoo.co.uk <mailto:mike_k_houghton at 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 at haskell.org <mailto:Beginners at haskell.org>
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners <http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners>
>> 
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org <mailto:Beginners at haskell.org>
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/beginners/attachments/20180413/b774bbe0/attachment.html>


More information about the Beginners mailing list