Opened 7 years ago

Last modified 4 weeks ago

#3399 patch proposal

Generalize the type of Data.List.{deleteBy, deleteFirstsBy}

Reported by: iago Owned by:
Priority: normal Milestone: 8.2.1
Component: libraries/base Version: 6.10.4
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s): Phab:D2526
Wiki Page:


Better (more general) type signatures would be

deleteBy :: (b -> a -> Bool) -> b -> [a] -> [a]
deleteFirstsBy :: (b -> a -> Bool) -> [b] -> [a] -> [a]

Example of why it is useful:

deleteBy ((==) . fst) 1 [(1,'a'), (2, 'b')]

Change History (9)

comment:1 Changed 7 years ago by iago

Sorry, the example was wrong, it should be

deleteBy (\x -> (x ==) . fst) 1 [(1,'a'), (2, 'b')]


deleteBy ((==) . fst) (1,'a') [1,2]

comment:2 Changed 7 years ago by maeder

Your proposal shows to me that there is another generalization of delete (I think a better one than deleteBy), let's call it deleteFirst which is a variant of filter with a negated predicate, that stops immediately after one element has been removed.

deleteFirst :: (a -> Bool) -> [a] -> [a]
deleteFirst p l =
  let (ft, rt) = break p l
  in ft ++ drop 1 rt

delete :: Eq a => a -> [a] -> [a]
delete a = deleteFirst (== a)

(In the type signature of your above function deleteFirstsBy the argument lists '[a]' and '[b]' should be swapped, because the second argument is taken away from the first one.)

Maybe a better alternative for deleteFirstsBy would be deleteFirsts:

deleteFirsts :: [a -> Bool] -> [a] -> [a]
deleteFirsts fs l = foldr deleteFirst l fs

deleteFirstsBy :: (b -> a -> Bool) -> [a] -> [b] -> [a]
deleteFirstsBy eq l r = deleteFirsts (map eq r) l

But, since hardly anybody wants to touch Data.List, I would vote for closing this ticket

comment:3 Changed 7 years ago by iago

The proposal doesn't require change code itself, it is just use the more general type signature instead of restrict it unnecessary. The change wouldn't break any code.

comment:4 Changed 7 years ago by maeder

Another argument against this proposal is, that an "equality" function taking different argument types is rather unintuitive. Who actually needs this generalization and is able to understand this from the documentation? Orthogonality would also require to check if the other "By"-functions can be generalized to swallow an "(b -> a -> Bool)" argument. (Indeed intersectBy could be generalized, too.)

comment:5 Changed 7 years ago by igloo

  • difficulty set to Unknown
  • Milestone set to Not GHC

comment:6 Changed 6 years ago by igloo

  • Resolution set to wontfix
  • Status changed from new to closed
  • Type of failure set to None/Unknown

Looks like an abandoned proposal

comment:7 Changed 6 weeks ago by mpickering

  • Differential Rev(s) set to Phab:D2526
  • Milestone changed from Not GHC to 8.2.1
  • Resolution wontfix deleted
  • Status changed from closed to new

comment:8 Changed 6 weeks ago by mpickering

  • Status changed from new to patch

comment:9 Changed 4 weeks ago by bgamari

There was recently a discussion on the libraries list but it's not clear to me what the conclusion was.

Note: See TracTickets for help on using tickets.