Different Ways to Test if a List Contains Only Positive IntegersΒΆ

The following is a series of Haskell functions that all solve the following problem:

Write a function that takes a list of integers as input, and returns True if all of them are greater than 0, and False otherwise. The empty list should return True.

The purpose of this is to get practice with basic Haskell features. Some of these functions are inefficient, or do things in a needlessly tricky way. But that’s okay for now: the point is to try to learn basic Haskell syntax and techniques.

-- equations with if/then/else
all_pos1 :: [Int] -> Bool
all_pos1 []     = True
all_pos1 (x:xs) = if x <= 0 then False else all_pos1 xs

-- guarded equations
all_pos2 :: [Int] -> Bool
all_pos2 []     = True
all_pos2 (x:xs) | x <= 0    = False
                | otherwise = all_pos2 xs

-- Remove all numbers >= 0 from the list. If the resulting list is empty, then
-- the numbers were all positive. Otherwise, there are some negatives.
all_pos3 :: [Int] -> Bool
all_pos3 lst = null (filter (<=0) lst)

-- Same idea as all_pos3, but written in a point-free style, i.e. without an
-- explicit name for the input list. The "." is the function compose operator.
all_pos4 :: [Int] -> Bool
all_pos4 = null . (filter (<=0))

-- (all pred lst) is a prelude function that returns True if pred returns true
-- for every element of lst
all_pos5 :: [Int] -> Bool
all_pos5 lst = all (>0) lst

-- Point-free version of all_pos5.
all_pos6 :: [Int] -> Bool
all_pos6 = all (>0)

-- Using a right fold.
all_pos7 :: [Int] -> Bool
all_pos7 lst = foldr (\x y -> x > 0 && y) True lst

-- Using a left fold. Notice that the types of x and y in the folding function
-- have changed.
all_pos8 :: [Int] -> Bool
all_pos8 lst = foldl (\x y -> x && y > 0) True lst

-- Using a list comprehension. This is similar to the "filter" approach above,
-- but with the filter function replaced by a list comprehension.
all_pos9 :: [Int] -> Bool
all_pos9 lst = null [x | x <- lst, x <= 0]

-- Another solution using a list comprehension. The "and lst" functions
-- returns True just when every element of lst evalautes to True.
all_pos10 :: [Int] -> Bool
all_pos10 lst = and [x > 0 | x <- lst]

-- A variation of the previous function that uses map instead of a list
-- comprehension.
all_pos11 :: [Int] -> Bool
all_pos11 lst = and (map (>0) lst)

-- Point-free version of the previous function. "." is function composition.
all_pos12 :: [Int] -> Bool
all_pos12 = and . (map (>0))