-- Examples of using list comprehension import Data.Char -------------------------------------------------------------------------------- -- Operating on *all* elements in a list -- sumSquares n gives the sum of the squares of the numbers from 1 to n sumSquares :: Int -> Int sumSquares n = sum [x*x | x <- [1..n]] -- Change each character to upper case allCAPS :: String -> String allCAPS s = [toUpper c | c <- s] -- takeWords n s returns the first n words of s takeWords :: Int -> String -> String takeWords n s = unwords (take n (words s)) -- capitalize s capitalizes all words in s capitalize :: String -> String capitalize s = unwords [cap w | w <- words s] where cap (c:str) = toUpper c : str -------------------------------------------------------------------------------- -- Operating on *some* elements in a list (filtering) -- keepPositives as delete all negative numbers from as keepPositives :: [Int] -> [Int] keepPositives as = [a | a <- as, a >= 0] -- divisors n lists the (positive) divisors of n divisors :: Int -> [Int] divisors n = [m | m <- [1..n], mod n m == 0] -- isPrime n checks is n is a (positive) prime number isPrime :: Int -> Bool isPrime n = divisors n == [1,n] -- censor s deletes all lines in s which contain the word "money" censor :: String -> String censor s = unlines [ l | l <- lines s, "money" `notElem` words l] -------------------------------------------------------------------------------- -- Multiple list generators -- dices n returns the ways that a pair of dices can result in the sum n dices :: Int -> [(Int,Int)] dices n = [ (a,b) | a <- [1..6], b <- [1..6], a+b==n ] -- check_max n checks that the max function is correct for all arguments from 0 -- to n check_max :: Int -> Bool check_max n = and [ if a>b then max a b == a else max a b == b | a <- [0..n], b <- [0..n] ] -- closestPoints ps gives the distance between the closest (non-equal) points in -- the list ps closestPoints :: [(Double,Double)] -> Double closestPoints ps = minimum [ sqrt ((x1-x2)^2 + (y1-y2)^2) | p1@(x1,y1) <- ps , p2@(x2,y2) <- ps , p1 /= p2 ] -- @ is used to give a name to the expression matched by a pattern