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 |
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 |
In reply to this post by Mike Houghton
You will feel like this was obvious in hindsight. fmap (a -> b) -> EitherT m c a -> EitherT m c bfmap :: (a -> b) -> f a -> f 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 <[hidden email]> wrote: Hi, _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners |
In reply to this post by Mike Houghton
Hi, Try to unify the types returned by each of the case alternatives, starting from what the compiler has inferred so far. I’ve made this mistake many times lol. Best, toz On Thu, Apr 12, 2018 at 5:38 AM <[hidden email]> wrote: Send Beginners mailing list submissions to _______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners |
In reply to this post by David McBride
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
_______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners |
Even ‘better’ instance Monad m => Functor (EitherT m a) where fmap f m = EitherT $ runEitherT m >>= \mv -> return $ fmap f mv :)
_______________________________________________ Beginners mailing list [hidden email] http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners |
Free forum by Nabble | Edit this page |