3

I want to remove every occurance of a certain value from a list. I have written a function to do this:

removeall val [] = []
removeall val list = if (head list) == val
                     then removeall val (tail list)
                     else (head list):(removeall val (tail list))

but I would like to use Prelude if possible for reasons of elegance and readability.

Don Stewart
  • 137,316
  • 36
  • 365
  • 468
Peter
  • 1,464
  • 1
  • 13
  • 18

4 Answers4

24
removeall = filter . (/=)
Edward Kmett
  • 29,632
  • 7
  • 85
  • 107
19
removeall val list = filter (/= val) list
Marat Salikhov
  • 6,367
  • 4
  • 32
  • 35
2

The following works as well

removeall val list = [ x | x <- list, x /= val ]
Chris Conway
  • 55,321
  • 43
  • 129
  • 155
1

This is just a rewrite of yours which removes the head and tail function calls.

removeall val [] = []
removeall val (x:xs) = if (x == val) 
                         then removeall val xs 
                         else x:removeall val xs

Personally I prefer the

removeall = filter . (/=)

one given by the others but that might be harder for a beginner to understand quickly.

  • The `filter . (/=)` version did make me stop and think for a bit, but I thought Peter's slightly more pointful `removeall val = filter (/= val)` was quite clear. – Chuck Aug 27 '09 at 20:55
  • The toughest thing about your second solution (and Haskell in general) is that the standard library is huge, so beginners don't know all the primitives (like map, mapAccumL, filter, foldl, zip, etc) – Peter Sep 07 '09 at 07:58
  • 2
    @Peter, it wasn't my suggestion but rather Edward Kmett's. I love the second solution for its concise nature but yes if I were a beginner I'd go for something along the lines of the first. And yes I agree, the standard library is huge but once you get to know most of it you're good to go :) – Andrew Calleja Sep 07 '09 at 18:51