EitherT

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

EitherT

Mike Houghton
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
Reply | Threaded
Open this post in threaded view
|

Re: EitherT

Francesco Ariis
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
Reply | Threaded
Open this post in threaded view
|

Re: EitherT

David McBride
In reply to this post by Mike Houghton
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 <[hidden email]> 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
Reply | Threaded
Open this post in threaded view
|

Re: EitherT

鲍凯文
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
        [hidden email]

To subscribe or unsubscribe via the World Wide Web, visit
        http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [hidden email]

You can reach the person managing the list at
        [hidden email]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1.  EitherT (mike h)


----------------------------------------------------------------------

Message: 1
Date: Thu, 12 Apr 2018 11:25:57 +0100
From: mike h <[hidden email]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[hidden email]>
Subject: [Haskell-beginners] EitherT
Message-ID: <[hidden email]>
Content-Type: text/plain; charset=utf-8

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





------------------------------

Subject: Digest Footer

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


------------------------------

End of Beginners Digest, Vol 118, Issue 6
*****************************************

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: EitherT

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


On 12 Apr 2018, at 17:27, David McBride <[hidden email]> 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 <[hidden email]> 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


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: EitherT

Mike Houghton
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 <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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



_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners