-- list constructors [], (:), commonly used list functions head, tail, ++, length. -- the concept of currying and partial application. -- f :: a -> b -- g :: (a , b) -> c -- curry(g) :: a -> (b -> c) == a -> b -> c -- "->" is right associative. -- x :: a -- y :: b -- curry(g) x :: b -> c -- (curry(g) x) y == curry(g) x y :: c -- function application is left associative. -- Defining functions in Haskell. -- 1. Defining functions from existing ones. add :: Int -> Int -> Int add x y = x + y appendLength :: [a] -> [a] -> Int appendLength x y = length (x ++ y) -- 1.5, if-then-else and recursion. -- 0 ! = 1 -- n ! = n * ((n-1)!) -- we assume input n to be nonnegative. factorial :: Int -> Int factorial n = if n == 0 then 1 else if n > 0 then n * (factorial (n-1)) else error "n is negative" factorial' :: Int -> Int factorial' n | n == 0 = 1 factorial' n | n > 0 = n * (factorial' (n -1)) factorial' n = error "n is negative" -- factorial 4 = 4 * factorial 3 -- = 4 * (3 * factorial 2) -- = 4 * (3 * (2 * factorial 1)) -- = 4 * (3 * (2 * 1 * (factorial 0))) -- = 4 * (3 * (2 * 1 * 1)) -- 2. Define function by pattern matching and recursion. -- length, head, tail, append, zip. first :: (a, b) -> a first (x, y) = x second :: (a, b) -> b second (x, y) = y length' :: [a] -> Int length' [] = 0 length' (x:xs) = 1 + length' xs append :: [a] -> [a] -> [a] append [] y = y append (x:xs) y = x : append xs y -- append' :: [a] -> [a] -> [a] -- append' x [] = x -- append' x (y:ys) = append' (append' x [y]) ys -- append [1, 2] [3 4] == append (1:(2:[])) (3:(4:[])) = ... = -- 1:2:3:4:[] -- length'' :: [a] -> Int -- length'' l | l == [] = 0 -- length'' l | l == x:xs = 1 + length'' xs -- length' ('a':('b':('c':[]))) = 1 + length' ('b':('c':[])) -- 1 + (1 + length' ('c':[])) = 1 + 1 + (1 + length' []) = 1 + 1 + 1 + 0 = 3