# curried function

Prelude> max 1 2
2
Prelude> (max 1) 2
2


Prelude> :t max
max :: Ord a => a -> a -> a
Prelude> :t max
max :: Ord a => a -> (a -> a)


-- addThree - adds three numbers, returns their sum
addThree :: (Num a) => a -> a -> a -> a
addThree x y z = x + y + z


*Main> addThree 1 2 3
6
6


{- isUpper - if a character is uppercase, return True,
otherwise, return False.
-}
isUpper :: Char -> Bool
isUpper = (elem ['A'..'Z'])


# 其它的高阶函数

zip_with :: (a -> b -> c) -> [a] -> [b] -> [c]
zip_with _ [] _ = []
zip_with _ _ [] = []
zip_with func (xFirst:xRest) (yFirst:yRest) =
(func xFirst yFirst) : (zip_with func xRest yRest)


*Main> zip_with (*) [1, 2] [3, 4]
[3,8]
*Main> zip_with max [1, 2] [3, 4]
[3,4]


# 一些库函数

## map

map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (first:rest) = f first : map f rest


*Main> map fst [(1, 2), (3, 4)]
[1,3]
*Main> map (* 2) [1, 2, 3]
[2,4,6]


## filter

filter :: (a -> Bool) -> [a] -> [a]
filter _ [] = []
filter predicate (first:rest)
| predicate first = first : filter predicate rest
| otherwise = filter predicate rest


*Main> filter' (> 3) [1, 2, 3, 4]
[4]