1

I would like to have a function that checks if a list contains only even numbers; if so, it should return True, otherwise - False.

Functions I would like to use are map / filter / foldr, possibly without length.

Here is my attempt:

ListOfeven :: [Integral] -> Bool
ListOfeven xs = 
  | foldr (+) True filter odd xs < 0 = True
  | otherwise = False

I am pretty sure that there is a cleaner way.. isn't there any? :)

ljedrz
  • 20,316
  • 4
  • 69
  • 97
piggyback
  • 9,034
  • 13
  • 51
  • 80
  • To work from what you gave. First of all the guards are redundant – walpen Dec 08 '12 at 02:00
  • 1
    So, accidentally hit enter on last comment: reposting -- To work from what you gave. First of all the guards are redundant, also instead of checking whether the sum is nonzero, we can just check if the filtered list is non null (also your code has a bug, it fails for the list [0]). So the `foldr (+)` and `< 0` drops out and instead put in `not . null . filter odd`. Well `null . filter` == `any` so this turns into `not . all odd`. And `not . any foo` == `all (not . foo)` and since `not . odd` == `even`, we end up with the answer @Frerich Raabe gave `all even`. Hope that helps :). – walpen Dec 08 '12 at 02:07

3 Answers3

7

The easiest would be to just use the all function from the Prelude:

evenList = all even

If you insist on just using map, filter and foldr:

evenList = foldr (&&) True . map even
Frerich Raabe
  • 90,689
  • 19
  • 115
  • 207
5
myfunc = foldr (\a b -> even a && b) True
Satvik
  • 11,238
  • 1
  • 38
  • 46
1

Frerich's solution works well, but can be optimized just a touch:

evenList :: [Integer] -> Bool
evenList = foldr ((&&) . even) True

This will only run through the list once. The function composition here is a bit strange, but becomes more clear upon examining its type:

(&&) . even :: Integral a => a -> Bool -> Bool

The result of even, which takes a single argument, is then bound to the first argument to the && operator, used here in prefix notation.

fredugolon
  • 518
  • 3
  • 9
  • 2
    Did you benchmark this? I believe that `foldr (&&) True . map even` will also iterate the list just once because of stream fusion. See [this StackOverflow question](http://stackoverflow.com/questions/578063/what-is-haskells-stream-fusion) for what that is and how it works. – Frerich Raabe Dec 07 '12 at 18:28
  • 2
    Awesome! I suppose I should have done more extensive homework! Will investigate further. – fredugolon Dec 07 '12 at 19:00