fac1 :: Int -> Int
fac1 n = product [1..n]
fac1 5
fac :: Int -> Int
fac 0 = 1
fac n = n * fac (n-1)
fac 5
(#) :: Int -> Int -> Int
m # 0 = 0
m # n = m + (m # (n - 1))
4 # 3
(#) 4 3
4 * 3
(*) 4 3
product1 :: Num a => [a] -> a
product1 [] = 1
product1 (n:ns) = n * product1 ns
product1 [2,4,6]
length1 :: [a] -> Int
length1 [] = 0
length1 (_:xs) = 1 + length1 xs
length1 [1,2,3]
reverse1 :: [a] -> [a]
reverse1 [] = []
reverse1 (x:xs) = reverse xs ++ [x]
reverse1 [1,2,3]
(##) :: [a] -> [a] -> [a]
[] ## ys = ys
(x:xs) ## ys = x : (xs ## ys)
[1,2,3] ## [4,5,6]
[1,2,3] ++ [4,5,6]
insert :: Ord a => a -> [a] -> [a]
insert x [] = [x]
insert x (y:ys)
| x <= y = x : y : ys
| otherwise = y : insert x ys
insert 3 [1,2,4,5]
isort :: Ord a => [a] -> [a]
isort [] = []
isort (x : xs) = insert x (isort xs)
isort [4,3,6,5,9]
isort ["john","alice","jim"]
zip :: [a] -> [b] -> [(a,b)]
zip [] _ = []
zip _ [] = []
zip (x:xs) (y:ys) = (x,y) : zip xs ys
zip ['a','b','c'] [1,2,3,4]
drop :: Int -> [a] -> [a]
drop 0 xs = xs
drop _ [] = []
drop n (_:xs) = drop (n-1) xs
drop 3 [1,2,3,4,5,6]
fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n-2) + fib (n-1)
fib 4
qsort [] = []
qsort (x:xs) = qsort ys ++ [x] ++ qsort zs
where
ys = [a | a <- xs, a <= x]
zs = [b | b <- xs, b > x]
qsort [4,3,6,5,9]
even :: Int -> Bool
even 0 = True
even n = odd (n-1)
odd :: Int -> Bool
odd 0 = False
odd n = even (n-1)
even 8
even 13
odd 7
odd 20
evens :: [a] -> [a]
evens [] = []
evens (x:xs) = x : odds xs
odds :: [a] -> [a]
odds [] = []
odds (_:xs) = evens xs
evens "abcde"
STEP 1: Define the type
product :: [Int] -> Int
STEP 2: Enumerate the cases
product [] =
product (n:ns) =
STEP 3: Define the simple cases (base case)
product [] = 1
STEP 4: Define the other cases (recursive cases)
product (n:ns) = n * product ns
STEP 5: Generalize and simplify
product :: Num a => [a] -> a
product = foldr (*) 1
STEP 1: Define the type
drop :: Int -> [a] -> a
STEP 2: Enumerate the cases
drop 0 [] =
drop 0 (x:xs) =
drop n [] =
drop n (x:xs) =
STEP 3: Define the simple cases (base case)
drop 0 [] = []
drop 0 (x:xs) = x:xs
drop n [] = []
drop n (x:xs) =
STEP 4: Define the other cases (recutsive cases)
drop 0 [] = []
drop 0 (x:xs) = x:xs
drop n [] = []
drop n (x:xs) = drop (n-1) xs
STEP 5: Generalize and simplify
drop :: Integral b => b -> [a] -> a
drop 0 xs = xs
drop n [] = []
drop n (x:xs) = drop (n-1) xs
We can replace n by _ in 3rd equation
drop :: Integral b => b -> [a] -> a
drop 0 xs = xs
drop _ [] = []
drop n (x:xs) = drop (n-1) xs
STEP 1: Define the type
init :: [a] -> [a]
STEP 2: Enumerate the cases
init (x:xs) =
STEP 3: Define the simple cases (base case is 1-element list)
init (x:xs)
| null xs = []
| otherwise =
STEP 4: Define the other cases (recursive cases)
init (x:xs)
| null xs = []
| otherwise = x : init xs
STEP 5: Generalize and simplify (nothing to generalize here; but can be simplified)
init :: [a] -> [a]
init [_] = []
init (x:xs) = x : init xs
-- 7. merge
merge :: Ord a => [a] -> [a] -> [a]
merge [] xs = xs
merge xs [] = xs
merge (x:xs) (y:ys)
| x < y = x : merge xs (y:ys)
| otherwise = y : merge (x:xs) ys
merge [2,5,6] [1,3,4]
-- 8. mergesort
halve :: [a] -> ([a],[a])
halve [] = ([],[])
halve [x] = ([x],[])
halve (x1:x2:xs) = (x1:h1s,x2:h2s) where (h1s,h2s)= halve xs
msort :: Ord a => [a] -> [a]
msort [] = []
msort [x] = [x]
msort xs = merge (msort h1s) (msort h2s) where (h1s,h2s) = halve xs
halve [1,2,3,4,5,6]
msort [20,10,30,40,5,16,19,22]