Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
COSC 4P41 – Functional Programming Some functions id id x :: a -> a = x const const k _ :: a -> b -> a = k ($) f $ x :: (a -> b) -> a -> b = f x (.) (f . g) x :: (b -> c) -> (a -> b) -> (a -> c) = f (g x) flip flip f x y :: (a -> b -> c) -> b -> a -> c = f y x © M. Winter 2.1 COSC 4P41 – Functional Programming Recursion fac :: Int -> Int fac n | n == 0 | n > 0 = 1 = fac (n-1) * n fac :: Int -> Int fac n | n == 0 | n > 0 | otherwise = 1 = fac (n-1) * n = error ”fac only defined on natural numbers” © M. Winter 2.2 COSC 4P41 – Functional Programming Primitive Recursion fun :: Int -> Int fun n | n == 0 = … | n > 0 = … fun (n-1) … data Nat = Zero | Succ Nat fun :: Nat -> Nat fun Zero = … fun (Succ n) = … (fun n) … © M. Winter 2.3 COSC 4P41 – Functional Programming Tuples The type (t1,t2,…,tn) consists of tuples of values (v1,v2,…,vn) in which v1::t1,…,vn::tn. Examples: minAndMax :: Int -> Int -> (Int,Int) minAndMax x y | x >= y = (y,x) | otherwise = (x,y) type ShopItem = (String,Int) A type definition is treated as a shorthand in Haskell – wherever a name like ShopItem is used, it has exactly the same effect as if (String,Int) had been written. © M. Winter 2.4 COSC 4P41 – Functional Programming Pattern Matching addPair :: (Int,Int) -> Int addPair (x,y) = x+y shift :: ((Int,Int),Int) -> (Int,(Int,Int)) shift ((x,y),z) = (x,(y,z)) name :: ShopItem -> String price :: ShopItem -> Int name (n,p) = n price (n,p) = p fst :: (a,b) -> a fst (x,y) = x © M. Winter snd :: (a,b) -> b snd (x,y) = y 2.5 COSC 4P41 – Functional Programming Currying and Uncurrying multiply :: Int -> Int -> Int multiply x y = x*y multiplyUC :: (Int,Int) -> Int multiplyUC (x,y) = x*y curry g x (x,y) g y uncurry f x (x,y) f y © M. Winter 2.6 COSC 4P41 – Functional Programming Lists For the type t there is a Haskell type [t] of lists from t. [1,2,3,4,1,4] :: [Int] [True] :: [Bool] [’a’,’a’,’b’] :: [Char] ”aab” :: String but type String = [Char] [fac, (+1)] :: [Int -> Int] [] :: [a] © M. Winter 2.7 COSC 4P41 – Functional Programming Lists for enumerated types Lists of numbers, characters and other enumerated types • [n .. m] is the list [n,n+1,…,m]; if n exceeds m, the list is empty. [2 .. 7] = [2,3,4,5,6,7] [3.1 .. 7.0] = [3.1,4.1,5.1,6.1] [’a’ .. ’m’] = ”abcdefghijklm” • [n,p .. m] is the list of numbers whose first two elements are n and p with the numbers ascending in steps p-n up to m, [7,6 .. 3] = [7,6,5,4,3] [0.0,0.3 .. 1.0] = [0.0,0.3,0.6,0.9] [’a’,’c’ .. ’n’] = ”acegikm” © M. Winter 2.8 COSC 4P41 – Functional Programming List comprehension Suppose that the list ex is [2,4,7], then the list comprehension [ 2*n | n <- ex ] will be [4,8,14]. Further examples: [ 2*n | n <- ex, even n, n > 3] = [8] [ m+n | (m,n) <- [(2,3),(2,1),(7,8)] ] = [5,3,15] [ m+n | n <- ex, even n, m <- ex, odd m] = [9,11] List comprehension is not a new feature of the language. Each expression using list comprehension can be translated into an expression of the core language, i.e., without list comprehension. © M. Winter 2.9 COSC 4P41 – Functional Programming Some list functions in Prelude.hs -- data [a] = [] | a : [a] head head (x:_) :: [a] -> a = x last last [x] last (_:xs) :: [a] -> a = x = last xs tail tail (_:xs) :: [a] -> [a] = xs init init [x] init (x:xs) :: [a] -> [a] = [] = x : init xs null null [] null (_:_) :: [a] -> Bool = True = False © M. Winter 2.10 COSC 4P41 – Functional Programming (++) [] ++ ys (x:xs) ++ ys :: [a] -> [a] -> [a] = ys = x : (xs ++ ys) map map f xs :: (a -> b) -> [a] -> [b] = [ f x | x <- xs ] filter filter p xs :: (a -> Bool) -> [a] -> [a] = [ x | x <- xs, p x ] concat concat :: [[a]] -> [a] = foldr (++) [] length length :: [a] -> Int = foldl' (\n _ -> n + 1) 0 (!!) (x:_) (_:xs) (_:_) [] © M. Winter :: !! 0 = !! n | n>0 = !! _ = !! _ = [a] -> Int -> a x xs !! (n-1) error "Prelude.!!: negative index" error "Prelude.!!: index too large" 2.11 COSC 4P41 – Functional Programming foldl :: (a -> b -> a) -> a -> [b] -> a foldl f z [] = z foldl f z (x:xs) = foldl f (f z x) xs foldl1 foldl1 f (x:xs) :: (a -> a -> a) -> [a] -> a = foldl f x xs foldr :: (a -> b -> b) -> b -> [a] -> b foldr f z [] = z foldr f z (x:xs) = f x (foldr f z xs) foldr1 foldr1 f [x] foldr1 f (x:xs) :: (a -> a -> a) -> [a] -> a = x = f x (foldr1 f xs) iterate iterate f x :: (a -> a) -> a -> [a] = x : iterate f (f x) reverse reverse © M. Winter :: [a] -> [a] = foldl (flip (:)) [] 2.12 COSC 4P41 – Functional Programming take take n _ | n <= 0 take _ [] take n (x:xs) :: Int -> [a] -> [a] = [] = [] = x : take (n-1) xs drop drop n xs | n <= 0 drop _ [] drop n (_:xs) :: Int -> [a] -> [a] = xs = [] = drop (n-1) xs and, or and or :: [Bool] -> Bool = foldr (&&) True = foldr (||) False any, all any p all p :: (a -> Bool) -> [a] -> Bool = or . map p = and . map p elem, notElem elem notElem © M. Winter :: Eq a => a -> [a] -> Bool = any . (==) = all . (/=) 2.13 COSC 4P41 – Functional Programming sum, product sum product :: Num a => [a] -> a = foldl' (+) 0 = foldl' (*) 1 maximum, minimum :: Ord a => [a] -> a maximum = foldl1 max minimum = foldl1 min zip zip :: [a] -> [b] -> [(a,b)] = zipWith (\a b -> (a,b)) zipWith zipWith z (a:as) (b:bs) zipWith _ _ _ unzip unzip © M. Winter :: (a->b->c) -> [a]->[b]->[c] = z a b : zipWith z as bs = [] :: [(a,b)] -> ([a],[b]) = foldr (\(a,b) ~(as,bs) -> (a:as, b:bs)) ([], []) 2.14