Skip to content

Add flipped fmap

The Applicative apply <*> and Monadic bind >>= both have flipped variants: <**> and =<< respectively. The Functor fmap or <$> does not have such a flipped variant.

I would like to propose adding a flipped variant of <$> to Data.Functor:

(<$$>) ∷ Functor f ⇒ f α → (α → β) → f β
(<$$>) = flip (<$>)

infixl 4 <$>, <$$>

because of the following two reasons:

  • I often use <$> in the last expression of a do-expression to do a final transformation of the last monadic value. When the code of the transformation function is big and spans multiple lines it visually breaks the sequential nature of a do-expression:
do m1
   m2
   bigPieceOfCodeThatVisuallyBreaks
     theSequentialNatureOfADoExpression <$> m3 

I would rather like to see:

do m1
   m2
   m3 <$$> bigPieceOfCodeThatVisuallyBreaks
             theSequentialNatureOfADoExpression
  • Consistency. As already mentioned, Applicative and Monad have flipped variants but Functor does not. I like the consistency of:
(<$>)  ∷ Functor f ⇒ (α → β) → (f α → f β)
(<$$>) ∷ Functor f ⇒ f α → (α → β) → f β

(<*>)  ∷ Applicative f ⇒ f (α → β) → (f α → f β)
(<**>) ∷ Applicative f ⇒ f α → f (α → β) → f β

(>>=)  ∷ Monad f ⇒ f α → (α → f β) → f β
(=<<)  ∷ Monad f ⇒ (α → f β) → (f α → f β)

With regard to naming, I don't particularly like <$$> because it's undirectional. However so are <$>, <*> and <**>. I choose <$$> because it's consistent with <**>.

Trac metadata
Trac field Value
Version 6.12.1
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/base
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information