Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Comonad's <$$>

Given the following from fp-course:

class Functor f where
  (<$>) ::
    (a -> b)
    -> f a
    -> f b

class Functor f => Extend f where
  (<<=) ::
    (f a -> b)
    -> f a
    -> f b

I defined <$$> as so:

(<$$>) ::
  Comonad f =>
  (a -> b)
  -> f a
  -> f b
(<$$>) f fa = f <$> fa

However, I'm interested to know if there's another way to implement <$$> without using <$>. Is there? If so, please show it!

like image 735
Kevin Meredith Avatar asked Jan 23 '19 03:01

Kevin Meredith


Video Answer


1 Answers

You need the extract method of Comonad; Extend isn't enough to get away without fmap.

(<$$>)
  :: Comonad f
  => (a -> b)
  -> f a
  -> f b
f <$$> w = f . extract <<= w

This is basically how liftW is implemented in Control.Comonad.

Note also that you need <<= (or extend); extract and duplicate aren't sufficient. The situation is similar to that of Bind and Monad; you can implement fmap using >>= and pure, but not using >>= alone and not using join and pure.

like image 66
dfeuer Avatar answered Sep 27 '22 22:09

dfeuer