# EitherT

6 messages
Open this post in threaded view
|

## EitherT

 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 [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Re: EitherT

 On Thu, Apr 12, 2018 at 11:25:57AM +0100, mike h wrote: > 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) Tricky error! The signature for this fmap is:     fmap :: (b -> c) -> EitherT m a b -> EitherT m a c The offending line is:     Left _   -> return mv You *think* you are returning `Either a c`, but are you really? Type HINTS for more :P -F _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|

## Re: EitherT

 In reply to this post by Mike Houghton You will feel like this was obvious in hindsight.fmap :: (a -> b) -> f a -> f bfmap (a -> b) -> EitherT m c a -> EitherT m c bNow follow the types in your code.m :: EitherT m c amv :: Either c areturn 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 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 [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Open this post in threaded view
|