Defining Functions
Conditional Expression
- Always have an
else
branch
abs :: Int -> Int
abs n = if n >= 0 then n else -n
signum :: Int -> Int
signum n = if n < 0 then -1 else
if n == 0 then 0 else 1
Guarded Equation
- Catch-all condition
otherwise
is defined by otherwise = True
abs n
| n >= 0 = n
| otherwise = -n
Pattern Matching
_
: wildcard pattern
- Matched in order
- May not repeat variables
not :: Bool -> Bool
not False = True
not True = False
(&&) :: Bool -> Bool -> Bool
True && True = True
True && False = False
False && True = False
False && False = False
True && True = True
_ && _ = False
True && b = b
False && _ = False
List Pattern
:
: cons, adds elements to the start of the list
(x:xs)
- Only matches non-empty lists
- Must be parenthesized
head :: [a] -> a
head (x:_) = x
tail :: [a] -> [a]
tail (_:xs) = xs
Lambda Expression
- Can give a formal meaning to functions defined using currying
add x y = x + y
add x = \y -> x + y
add = \x -> \y -> x + y
- Useful when defining functions that return functions as results
const :: a -> b -> a
const x _ = x
const :: a -> (b -> a)
const x = \_ -> x
- Avoid naming functions used only once
odds n = map f [0..n-1]
where
f x = x * 2 + 1
odds n = map (\x -> x * 2 + 1) [0..n-1]
Section
op
between arguments -> curried function: (op)
before arguments
1 + 2
(+) 1 2
(1+) 2
(+2) 1
Curry & Uncurry
curry :: ((a, b) -> c) -> a -> b -> c
curry f = \x -> \y -> f (x, y)
uncurry :: (a -> b -> c) -> (a, b) -> c
uncurry f = \(x, y) -> f x y