Ticket #3962 (closed proposal: wontfix)

Opened 3 years ago

Last modified 3 years ago

Add flipped fmap

Reported by: basvandijk Owned by:
Priority: normal Milestone: Not GHC
Component: libraries/base Version: 6.12.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty:
Test Case: Blocked By:
Blocking: Related Tickets:

Description

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 <**>.

Attachments

flipped_fmap.dpatch Download (29.0 KB) - added by basvandijk 3 years ago.

Change History

Changed 3 years ago by basvandijk

Changed 3 years ago by tibbe

I'm not in favor of this proposal. Naming trivial compositions puts a complexity tax on all users of the library and we end up with 2*n operators instead of n operators and one flip function. It's trivial to define the function locally or in a helper module.

To elaborate: At work some of our core APIs have gotten dramatically more complex due to their maintainers allowing people, in interest to keep their own code cleaner, to add small helper functions to those APIs. This is now recognized as bad practice and discouraged with a call to "not fear the semicolon"! (We use mostly imperative languages at work.)

Changed 3 years ago by basvandijk

 This is the corresponding thread on libraries@…

Changed 3 years ago by igloo

  • milestone set to Not GHC

Changed 3 years ago by basvandijk

  • status changed from new to closed
  • resolution set to wontfix

There weren't enough votes to accept this proposal so I'm resolving it as 'wontfix'.

Note: See TracTickets for help on using tickets.