Ticket #4189 (closed proposal: wontfix)

Opened 3 years ago

Last modified 3 years ago

(<.>) operator (generalizing (.) to Functor)

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

Description

Currently there are following operators:

(<$>) :: (a -> b) -> f a -> f b
($) :: (a -> b) -> a -> b
(.) :: (b -> c) -> (a -> b) -> a -> c

However defining the operator that is to <$> as . is to $ is trivial:

(<.>) :: (b -> c) -> (a -> f b) -> a -> f c
f <.> g = fmap f . g

It would help writing in pointless style using Functors (as well as Applicatives/Monads etc.)

Attachments

composition.patch Download (43.2 KB) - added by uzytkownik 3 years ago.
Patch for composition of function in functors

Change History

  Changed 3 years ago by malcolm.wallace@…

The type you have chosen for <.> is far from obvious. Why not

(<.>) :: (b->c) -> (a->b) -> f a -> f c
f <.> g = ((f . g) <$>)

for instance?

  Changed 3 years ago by uzytkownik

1. Because it follows simple correspondence:

(a . b . c) d = a $ b $ c $ d
(a <.> b <.> c) d = a <$> b <$> c  <$> d

2. Because your definition does not allow chaining (well - the whiole point of such operator is chaining) [I know it is 'for example']:

\a b c -> a <.> b <.> c :: (Functor f, Functor f1) => (f c1 -> c) -> (b -> c1) -> (a -> b) -> f1 (f a) -> f1 c

or

\a b c -> a <.> b <.> c :: (Functor f, Functor f1) => (b -> c) -> (a -> b) -> (a1 -> f a) -> f1 a1 -> f1 (f c)

3. I decided to post it when I found  others find it useful as well - with the same definition.

4. It allows to chain even if first function parameter is not functor:

read <.> readFile :: (Read a) => FilePath -> IO a
print <=< (read :: String -> Int) <.> readFile :: FilePath -> IO ()
const 1 <.> print <=< (read :: String -> Int) <.> readFile :: (Num t) => FilePath -> IO t

follow-up: ↓ 4   Changed 3 years ago by igloo

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

I suggest making a  library proposal for this.

in reply to: ↑ 3 ; follow-up: ↓ 6   Changed 3 years ago by uzytkownik

Replying to malcolm.wallace@…:

The type you have chosen for <.> is far from obvious. Why not {{{ (<.>) :: (b->c) -> (a->b) -> f a -> f c f <.> g = ((f . g) <$>) }}} for instance?

I thought about more Cathegorical explanation. Functor F from A to B is suppose to map category into other category. I.e. if category A = (O, M, id, .) and B = (F(O), F(M), F(id), F(.)) then F(O) is solved on type level, F(M) is done by fmap, F(id) is fmap id and F(.) is <.>

Replying to igloo:

I suggest making a  library proposal for this.

I'll do it

  Changed 3 years ago by uzytkownik

  • status changed from closed to new
  • type changed from feature request to proposal
  • resolution wontfix deleted

in reply to: ↑ 4   Changed 3 years ago by uzytkownik

Replying to uzytkownik:

Replying to malcolm.wallace@…:

The type you have chosen for <.> is far from obvious. Why not {{{ (<.>) :: (b->c) -> (a->b) -> f a -> f c f <.> g = ((f . g) <$>) }}} for instance?

I thought about more Cathegorical explanation. Functor F from A to B is suppose to map category into other category. I.e. if category A = (O, M, id, .) and B = (F(O), F(M), F(id), F(.)) then F(O) is solved on type level, F(M) is done by fmap, F(id) is fmap id and F(.) is <.>

Please ignore this explanation.

Changed 3 years ago by uzytkownik

Patch for composition of function in functors

  Changed 3 years ago by igloo

  • milestone set to Not GHC

  Changed 3 years ago by uzytkownik

Summary of  discussion.

There were the following counterpoints to (<.>):

- Lack of symmetry (contrary to (.)) - Operators usually have more then 2 parameters in unexpanded form (however (>=>) (<=<) (<<) etc. are in base) - f <.> g is not much shorter then fmap f . g

Generally it seems to depend on style preference

  Changed 3 years ago by igloo

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

From a quick skim of the thread, I count 4 or 5 against the proposal, and 2 (including the proposer) in favour of it. I'm therefore closing it as wontfix; please reopen if you think I've reached the wrong conclusion.

Note: See TracTickets for help on using tickets.