Xs ++ Concat Xss

Xs ++ Concat Xss

RECURSIVE LIST PROCESSING CONTINUED Concatenating sublists: ➜ Lists can be nested, e.g., [[5, 6, 2], [], [4, 2]] :: [[Int]] ➜ concat merges sublists into one list, e.g., concat [[5, 6, 2], [], [4, 2]] ⇒ [5, 6, 2, 4, 2] ➜ We may specify the functionality of concat as concat [xs1, xs2, ... , xsn] = xs1 ++ xs2 ++ ··· ++ xsn ✧ Full definition: concat :: [[a]] -> [a] concat [] = [] concat (xs:xss) = xs ++ concat xss RECURSIVE LIST PROCESSING CONTINUED 1 RECURSIVE LIST PROCESSING CONTINUED Concatenating sublists: ➜ Lists can be nested, e.g., [[5, 6, 2], [], [4, 2]] :: [[Int]] ➜ concat merges sublists into one list, e.g., concat [[5, 6, 2], [], [4, 2]] ⇒ [5, 6, 2, 4, 2] ➜ We may specify the functionality of concat as concat [xs1, xs2, ... , xsn] = xs1 ++ xs2 ++ ··· ++ xsn ✧ Full definition: concat :: [[a]] -> [a] concat [] = [] concat (xs:xss) = xs ++ concat xss RECURSIVE LIST PROCESSING CONTINUED 1-A Appending a list: ➜ The function ++ is an infix operator (Functions with alphanumeric names are used prefix) (++) :: [a] -> [a] -> [a] ➜ ++ consumes and simultaneously produces a list ➜ Let us look at [5, 6, 2] ++ [4, 2]: (5:(6:(2:[]))) ++ (4:(2:[])) ⇒ 5:(6:(2:(4:(2:[])))) ➜ What can we observe? Essentially, ++ replaces the [] of the first list with the second list. ✧ Full definition: (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) RECURSIVE LIST PROCESSING CONTINUED 2 Appending a list: ➜ The function ++ is an infix operator (Functions with alphanumeric names are used prefix) (++) :: [a] -> [a] -> [a] ➜ ++ consumes and simultaneously produces a list ➜ Let us look at [5, 6, 2] ++ [4, 2]: (5:(6:(2:[]))) ++ (4:(2:[])) ⇒ 5:(6:(2:(4:(2:[])))) ➜ What can we observe? Essentially, ++ replaces the [] of the first list with the second list. ✧ Full definition: (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) RECURSIVE LIST PROCESSING CONTINUED 2-A Appending a list: ➜ The function ++ is an infix operator (Functions with alphanumeric names are used prefix) (++) :: [a] -> [a] -> [a] ➜ ++ consumes and simultaneously produces a list ➜ Let us look at [5, 6, 2] ++ [4, 2]: (5:(6:(2:[]))) ++ (4:(2:[])) ⇒ 5:(6:(2:(4:(2:[])))) ➜ What can we observe? Essentially, ++ replaces the [] of the first list with the second list. ✧ Full definition: (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) RECURSIVE LIST PROCESSING CONTINUED 2-B Appending a list: ➜ The function ++ is an infix operator (Functions with alphanumeric names are used prefix) (++) :: [a] -> [a] -> [a] ➜ ++ consumes and simultaneously produces a list ➜ Let us look at [5, 6, 2] ++ [4, 2]: (5:(6:(2:[]))) ++ (4:(2:[])) ⇒ 5:(6:(2:(4:(2:[])))) ➜ What can we observe? Essentially, ++ replaces the [] of the first list with the second list. ✧ Full definition: (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) RECURSIVE LIST PROCESSING CONTINUED 2-C Stepwise execution of ++: (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) Let us look at [5, 6, 2] ++ [4, 2]: (5:(6:(2:[]))) ++ (4:(2:[])) (1) ⇒ 5:( (6:(2:[])) ++ (4:(2:[])) ) (2) ⇒ 5:(6:( (2:[]) ++ (4:(2:[])) )) (3) ⇒ 5:(6:(2:( [] ++ (4:(2:[])) ))) (4) ⇒ 5:(6:(2:( 4:(2:[]) ))) (5) RECURSIVE LIST PROCESSING CONTINUED 3 Stepwise execution of ++: (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) Let us look at [5, 6, 2] ++ [4, 2]: (5:(6:(2:[]))) ++ (4:(2:[])) (1) ⇒ 5:( (6:(2:[])) ++ (4:(2:[])) ) (2) ⇒ 5:(6:( (2:[]) ++ (4:(2:[])) )) (3) ⇒ 5:(6:(2:( [] ++ (4:(2:[])) ))) (4) ⇒ 5:(6:(2:( 4:(2:[]) ))) (5) RECURSIVE LIST PROCESSING CONTINUED 3-A Stepwise execution of ++: (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) Let us look at [5, 6, 2] ++ [4, 2]: (5:(6:(2:[]))) ++ (4:(2:[])) (1) ⇒ 5:( (6:(2:[])) ++ (4:(2:[])) ) (2) ⇒ 5:(6:( (2:[]) ++ (4:(2:[])) )) (3) ⇒ 5:(6:(2:( [] ++ (4:(2:[])) ))) (4) ⇒ 5:(6:(2:( 4:(2:[]) ))) (5) RECURSIVE LIST PROCESSING CONTINUED 3-B Stepwise execution of ++: (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) Let us look at [5, 6, 2] ++ [4, 2]: (5:(6:(2:[]))) ++ (4:(2:[])) (1) ⇒ 5:( (6:(2:[])) ++ (4:(2:[])) ) (2) ⇒ 5:(6:( (2:[]) ++ (4:(2:[])) )) (3) ⇒ 5:(6:(2:( [] ++ (4:(2:[])) ))) (4) ⇒ 5:(6:(2:( 4:(2:[]) ))) (5) RECURSIVE LIST PROCESSING CONTINUED 3-C Stepwise execution of ++: (++) :: [a] -> [a] -> [a] [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) Let us look at [5, 6, 2] ++ [4, 2]: (5:(6:(2:[]))) ++ (4:(2:[])) (1) ⇒ 5:( (6:(2:[])) ++ (4:(2:[])) ) (2) ⇒ 5:(6:( (2:[]) ++ (4:(2:[])) )) (3) ⇒ 5:(6:(2:( [] ++ (4:(2:[])) ))) (4) ⇒ 5:(6:(2:( 4:(2:[]) ))) (5) RECURSIVE LIST PROCESSING CONTINUED 3-D POLYMORPHISM ➜ We used head, tail, null, concat, and ++ only on lists containing integers ➜ But they are not restricted to integer lists head ["a string", "another string"] ⇒ "a string" null [2.3, 4.1, 9.52] ⇒ False [False, True, True] ++ [False] ⇒ [False, True, True, False] Thus, we call them polymorphic functions. POLYMORPHISM 4 Types of polymorphic functions: head :: [a] -> a tail :: [a] -> [a] null :: [a] -> Bool concat :: [[a]] -> [a] (++) :: [a] -> [a] -> [a] fst :: (a, b) -> a snd :: (a, b) -> b ➜ We call the a in [a] a type variable ➜ A type variable is a placeholder for a concrete type (just as an argument variable is placeholder for a concrete argument value) ✧ POLYMORPHISM 5 Types of polymorphic functions: head :: [a] -> a tail :: [a] -> [a] null :: [a] -> Bool concat :: [[a]] -> [a] (++) :: [a] -> [a] -> [a] fst :: (a, b) -> a snd :: (a, b) -> b ➜ We call the a in [a] a type variable ➜ A type variable is a placeholder for a concrete type (just as an argument variable is placeholder for a concrete argument value) ✧ POLYMORPHISM 5-A (++) :: [a] -> [a] -> [a] -- general type ➜ When using a polymorphic function, we can instantiate the type variables to any concrete type: (++) :: [Int] -> [Int] -> [Int] -- These are (++) :: [Float] -> [Float] -> [Float] -- instances of (++) :: [Bool] -> [Bool] -> [Bool] -- (++) ➜ Consistency: All occurrences of a type variable have to be replaced by the same concrete type (++) :: [Int] -> [Bool] -> [Int] -- WRONG! ➜ Important: Type variables must start with a lowercase letter Good names: a, ty, elem, elem1, elementType Incorrect names: A, Elem, 1elem ➜ Conversely, names of concrete types always start with an uppercase letter POLYMORPHISM 6 (++) :: [a] -> [a] -> [a] -- general type ➜ When using a polymorphic function, we can instantiate the type variables to any concrete type: (++) :: [Int] -> [Int] -> [Int] -- These are (++) :: [Float] -> [Float] -> [Float] -- instances of (++) :: [Bool] -> [Bool] -> [Bool] -- (++) ➜ Consistency: All occurrences of a type variable have to be replaced by the same concrete type (++) :: [Int] -> [Bool] -> [Int] -- WRONG! ➜ Important: Type variables must start with a lowercase letter Good names: a, ty, elem, elem1, elementType Incorrect names: A, Elem, 1elem ➜ Conversely, names of concrete types always start with an uppercase letter POLYMORPHISM 6-A (++) :: [a] -> [a] -> [a] -- general type ➜ When using a polymorphic function, we can instantiate the type variables to any concrete type: (++) :: [Int] -> [Int] -> [Int] -- These are (++) :: [Float] -> [Float] -> [Float] -- instances of (++) :: [Bool] -> [Bool] -> [Bool] -- (++) ➜ Consistency: All occurrences of a type variable have to be replaced by the same concrete type (++) :: [Int] -> [Bool] -> [Int] -- WRONG! ➜ Important: Type variables must start with a lowercase letter Good names: a, ty, elem, elem1, elementType Incorrect names: A, Elem, 1elem ➜ Conversely, names of concrete types always start with an uppercase letter POLYMORPHISM 6-B (++) :: [a] -> [a] -> [a] -- general type ➜ When using a polymorphic function, we can instantiate the type variables to any concrete type: (++) :: [Int] -> [Int] -> [Int] -- These are (++) :: [Float] -> [Float] -> [Float] -- instances of (++) :: [Bool] -> [Bool] -> [Bool] -- (++) ➜ Consistency: All occurrences of a type variable have to be replaced by the same concrete type (++) :: [Int] -> [Bool] -> [Int] -- WRONG! ➜ Important: Type variables must start with a lowercase letter Good names: a, ty, elem, elem1, elementType Incorrect names: A, Elem, 1elem ➜ Conversely, names of concrete types always start with an uppercase letter POLYMORPHISM 6-C (++) :: [a] -> [a] -> [a] -- general type ➜ When using a polymorphic function, we can instantiate the type variables to any concrete type: (++) :: [Int] -> [Int] -> [Int] -- These are (++) :: [Float] -> [Float] -> [Float] -- instances of (++) :: [Bool] -> [Bool] -> [Bool] -- (++) ➜ Consistency: All occurrences of a type variable have to be replaced by the same concrete type (++) :: [Int] -> [Bool] -> [Int] -- WRONG! ➜ Important: Type variables must start with a lowercase letter Good names: a, ty, elem, elem1, elementType Incorrect names: A, Elem, 1elem ➜ Conversely, names of concrete types always start with an uppercase letter POLYMORPHISM 6-D (++) :: [a] -> [a] -> [a] -- general type ➜ When using a polymorphic function, we can instantiate the type variables to any concrete type: (++) :: [Int] -> [Int] -> [Int] -- These are (++) :: [Float] -> [Float] -> [Float] -- instances of (++) :: [Bool] -> [Bool] -> [Bool] -- (++) ➜ Consistency: All occurrences of a type variable have to be replaced by the same concrete type (++) :: [Int] -> [Bool] -> [Int] -- WRONG! ➜ Important: Type variables must start with a lowercase letter Good names: a, ty, elem, elem1, elementType Incorrect names: A, Elem, 1elem ➜ Conversely, names of concrete types always start with an uppercase letter POLYMORPHISM 6-E (++) :: [a] -> [a] -> [a] --

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    30 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us