Functions
4.1 Defining and Calling Functions
Function application binds tightest: f x + 1 means (f x) + 1.
square :: Int -> Int
square x = x * x
add :: Int -> Int -> Int
add x y = x + y
main :: IO ()
main = do
print (square 5) -- 25: function application is just a space
print (add 2 3) -- 5
print (add 2 (square 3)) -- 11: parentheses group arguments
print (square $ add 1 2) -- 9: $ is low-precedence application4.2 Currying and Partial Application
-- add :: Int -> Int -> Int really means add :: Int -> (Int -> Int)
addFive :: Int -> Int
addFive = add 5 -- partial application returns a new function
doubleAll :: [Int] -> [Int]
doubleAll = map (* 2) -- operator section
-- Sections
(+ 1) 5 -- 6
(2 ^) 10 -- 1024 (2 ^ 10)
(^ 2) 10 -- 100 (10 ^ 2)
(`div` 2) 9 -- 4
subtract 1 10 -- 9 (note: (- 1) is the number -1, not a section)4.3 Operators as Functions and Functions as Operators
(+) 3 4 -- 7: an operator in parentheses is a prefix function
3 `add` 4 -- 7: a function in backticks is an infix operator
infixl 6 |+| -- declare fixity: infixl/infixr/infix with precedence 0–9
(|+|) :: (Int, Int) -> (Int, Int) -> (Int, Int)
(a, b) |+| (c, d) = (a + c, b + d)4.4 Lambdas, Composition and Point-Free Style
map (\x -> x * x + 1) [1, 2, 3] -- [2, 5, 10]: anonymous function
(\x y -> x + y) 3 4 -- 7
-- Composition: (f . g) x = f (g x)
countWords :: String -> Int
countWords = length . words -- point-free (no explicit argument)
process :: [Int] -> Int
process = sum . map (* 2) . filter even
-- $ avoids parentheses; & (Data.Function) is reverse application
result1 = sum (map (* 2) (filter even [1 .. 10]))
result2 = sum $ map (* 2) $ filter even [1 .. 10]
result3 = [1 .. 10] & filter even & map (* 2) & sum -- import Data.Function ((&))4.5 Conditional Expressions
classify :: Int -> String
classify n = if n < 0 then "negative" else if n == 0 then "zero" else "positive"
describe :: Int -> String
describe n = case compare n 0 of
LT -> "negative"
EQ -> "zero"
GT -> "positive"