Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
pp:l02 [2020/03/12 14:40]
pdmatei
pp:l02 [2021/03/16 19:24] (current)
roxana_elena.stiuca [2.3. Strings in Haskell]
Line 1: Line 1:
-====== Pattern matching and basic types in Haskell ======+====== ​2. Pattern matching and basic types in Haskell ======
  
-21Extract the fourth element from a list of integers:+===== 2.1. Pattern matching =====
  
-f l = head (tail (tail (tail l))))+It is likely that in the above implementations you used ''​head''​ and ''​tail'',​ or branch definitions combined with '​_'​ to solve the exercises. Haskell supports a more elegant means of //value introspection//,​ called **pattern matching**. For instance, in:
  
-22Write the same function which returns 0 if the list contains less that four elements.+<code haskell>​ 
 +f [] = ..
 +f (h:t) = ... 
 +</​code> ​
  
-[] = 0 +''​(h:​t)''​ is a **pattern** which denotes a non-empty list where ''​h''​ is the first element and ''​t''​ is the rest of the list. In fact, ''​[]''​ is also a pattern denoting the empty lists. Patterns are **allways** surrounded by round parentheses. They can also be compositeas in the exercise below:
-f [_] = 0 +
-f [_,_] = 0 +
-f [_,_,_] = 0 +
-f l = head (tail (tail (tail l))))+
  
-23In Haskell, one can use patterns to examine ​the contents ​of lists, pairs and other dataypes.+2.1.1. Write a function which returns ​the number ​of elements from a list. Use patterns.
  
-f (x:y:z:w:l= w +2.1.2. Write a function which takes a list of integer lists, and concatenates them. (E.g. ''​[ [1,​2,​3],​[4,​5] ] = [1,​2,​3,​4,​5]''​). 
-f _ = 0+ 
 +2.1.3 (!) Write the **same** function, this time using only the **cons** (''​:''​operator as well as **patterns**. ​
  
-   What types have x,y,z,w ? What type does have l ?+2.1.4. Write a function which removes duplicates from a list of integers.
  
-What about:+===== 2.2. Types in Haskell =====
  
 +2.2.1. What are the types of ''​x,​y,​z,​w''​ and that of ''​l''​ in the implementation below?
 +<code haskell>
 f (x:y:z:w:l) = w f (x:y:z:w:l) = w
 +f _ = 0
 +</​code>​
  
-   What is the difference?+How about: 
 +<code haskell>​ 
 +f (x:y:z:w:l) = w 
 +</​code>​ 
 +What is the difference?
     ​     ​
-24Write a function which filters out all negative numbers: +2.2.2. What is the type of the function: 
- +<code haskell>
-f [] = [] +
-f (x:xs) =  +
- | x > 0 = x:(f xs) +
- | otherwise = f xs +
- +
-25. What is the type of the function: +
 f x y = (x,y) f x y = (x,y)
 +</​code>​
  
-[[discussion on pairs]] f :a -> b -> (a,b) +In the body of a function definition, '',''​ is a **base constructor** for pairs. The following are pairs: ​''​(1,2), ("​Matei",​20),​ ([1,​2],​3)''​Note that there is no restriction on the type of the first and second values of a pair. 
- +
-26What is the type of the function:+
  
 +2.2.3. What is the type of the function:
 +<code haskell>
 f '​a'​ _ = [] f '​a'​ _ = []
 f x y = x:y f x y = x:y
 +</​code>​
  
-[[discussion on strings]] f :: Char -> String -> String+In Haskell, the type ''​String''​ is equivalent to ''​[Char]''​ (hence ​strings ​are lists of chars). Strings can be introspected using patterns just like any other list.
  
 +2.2.4. Let f be the function below:
 +<code haskell>
 +    f "​321CB"​ [("​321CB",​ ["​Matei",​ "​Andrei",​ "​Mihai"​]),​ ("​322CB",​["​George",​ "​Matei"​])] = ["​Matei",​ "​Mihai"​]
 +</​code>​
  
-27. Let "​321CB"​ [("​321CB",​ ["​Matei",​ "​Andrei",​ "​Mihai"​]),​ ("​322CB",​["​George,​ Matei"​])] +What is the signature of ''​f''?​
-  = ["​Matei",​ "​Mihai"​]+
  
-What is the signature of f? 
- f :: String -> [(String,​[String])] -> [String] 
  
-What does f do?+===== 2.3. Strings in Haskell =====
  
-Write an implementation for f:+2.3.1. ​Write a function which takes a list of words and makes the first letter of each word uppercase.
  
-f x [] = [] +2.3.2. Write a function which takes a list of words and makes **all** letters uppercase.
-f x ((y,​l):​ys) ​  +
-  | x == y = getM l +
-  | otherwise = f x ys +
-    where +
-        getM [] = [] +
-        getM ((x:l):xs)  +
-          | x == '​M'​ = (x:l):(getM xs) +
-          | otherwise = getM xs+
  
-28. Write a function which returns ​true if the third largest element from a list is positive+2.3.3. (!) Write a function which takes a text and a pattern and returns the number of occurrences of the pattern in the text.  
 +Example: 
 +<code haskell>  
 +search "I eat green apples"​ "​eat"​ = 1 
 +search "​ababaab"​ "​aba"​ = 2 
 +</​code>​
  
-f l = g (reverse (sort l)+2.3.4. ​(!What does ''​f'',​ defined in exercise 2.2.4., do (note that ''​Matei''​ and ''​Mihai''​ both start with letter '​M'​)? Write an implementation for ''​f''​.
- where g (x:y:z:_+
- | z > 0 = True +
- | otherwise = False +
-   g _ = False+
  
-29Sometimes it really helps to define function via function compositionFor instance:+2.3.5. Write the signature and implement the following function: 
 +<code haskell>​ 
 +   f ["​Matei",​ "​Mihai"​] ["​Popovici","​Dumitru"​] = [("​Matei","​Popovici"​),​ ("​Mihai","​Dumitru"​)] 
 +</​code>​
  
-f x = (g.h) x +2.3.6. Implement ​the following function: 
- where g x = 2*x +<code haskell> 
-       h x = x + 1 +   ​["​Matei",​ "​Mihai"​] ["​Popovici","​Dumitru"​] ​["​MPopovici"​"​MDumitru"​] 
- +</code>
-What type does f have? +
-What type does g have? +
- +
-What does the following function do? +
- +
-f x = ff x +
- where g x = 2*x +
-       h x = x + 1 +
-       ff = f.+
- +
-What does the following function ​do? +
- +
-f x = ff x +
- where g x = 2*x +
-       h x = x + 1 +
-       ff = h.f +
- +
- +
- +
-30. Rewrite exercise 28 via function composition+
- +
-(g . reverse . sort) l +
-      where ... +
- +
- +
-31.(hard) Write a function which takes a list of pairs - student-name and graderemoves +
-    those with grades ​<5, splits the name in substrings, and adds one point bonus to +
-    people with three names:+
  
 +2.3.7. Write a function which takes a list of pairs - student-name and grade, removes those with grades less than 5, splits the name in substrings, and adds one bonus point to people with three names. Example:
 +<code haskell>
     f [("Dan Matei Popovici",​9),​("​Mihai",​4),​("​Andrei Alex",​6)] =     f [("Dan Matei Popovici",​9),​("​Mihai",​4),​("​Andrei Alex",​6)] =
-    [(["​Dan",​ "​Matei",​ "​Popovici"​],​10),​(["​Andrei,​Alex"​],​6)] +    [(["​Dan",​ "​Matei",​ "​Popovici"​],​10),​(["​Andrei""Alex"​],​6)] 
- +</code>
-f l = (bonus . splall . rem) l +
- where rem [] = [] +
-   rem ((s,x):xs)  +
-   | x 5 = rem xs +
-   | otherwise = (s,x):(rem xs) +
- ​  ​ spl [] [] rest = rest +
- ​  ​ spl [] w rest = w:rest +
- ​  ​ spl (x:xs) w rest  +
- ​  ​ | x == ' ' = spl xs [] (w:rest) +
- ​  ​ | otherwise = spl xs (x:w) rest  +
-   splall [] = [] +
- ​  ​ splall ((s,x):xs) = ((spl s),​x):​(splall xs) +
- ​  ​ bonus [] = [] +
- ​  ​ bonus ((l,​x):​xs) +
- ​  ​ | (length l) == 3 = (l,​x+1):​(bonus xs) +
- ​  ​ | otherwise = (l,​x):​(bonus xs) +
- +
-32. Write the signature and implement the following function: +
-    +
-   f ["​Matei",​ "​Mihai"​] ["​Popovici"​] ["​Dumitru"​] = [("​Matei","​Popovici"​),​ ("​Mihai","​Dumitru"​)] +
- +
-   f :: [String] -[String] -> [(String,​String)] +
-   f (x:xs) (y:ys) = (x,y):(f xs ys) +
- +
-33. Implement the following function: +
- +
-   f ["​Matei",​ "​Mihai"​] ["​Popovici"​] ["​Dumitru"​] = ["​MPopovici",​ "​MDumitru"​] +
- +
-   f (((c:​_):​xs)) (y:ys) = (c:y):(f xs ys) +
- +
-34. Sometimes it helps to use functions in infix form. For instance: +
- +
- instead of mod x 2, we can write x `mode` 2. We can also define functions infix: +
- +
- x `f` y = x + y +
- +
- Implement an abbreviation function for exercise 31 and use it infix: +
- +
- f (x:ys) (y:ys) = (x `conc` y):(f xs ys) +
- where (x:_) `conc` s = x:s +
- +
-35. Just in the same way, we can treat infix functions as prefix.  +
- :t (+) +
- :t (&&​) +
- :t (++) +
- +
-36. What about function composition?​ Is it a special operator, or is it just a function as well? +
-  +
- :t (.) +
- +
-37. What does the function below do? +
- +
-f l = (((++) "?"​).((:​) '>'​)) l +
- +
- +
-How about? +
- +
-f = (((:) '>'​).(++"?"​)) +
- +
-38. Write a function of a single line, such that: +
- +
-f "​Matei"​ = "​[Matei]"​ +
- +
-f = ("​["​++).(++"​]"​) +
- +
-39. Use only (:) to solve exercise 38  +
- +
-f = ((:) '​['​) . reverse . ((:) '​]'​) . reverse +
- +
-40. What does the function ($) to?  +
-    (Use :t, and make up some tests) +
- +
-41. Write the following implementation using only ($): +
- +
-f "​||"​ "​Matei"​ = "​||Matei||"​+
  
-f s l = (s++) $ h $ (++s) $ reverse l 
  
  
-42.  Solve exercise 13. from [[Lab 2 | pp:l02]] using $ and other improvements (treat the case when the list has 
-     fewer elements): 
  
-   f l = g $ reverse l 
-   ​ where g (_:_:x:_) = not $ x `mod` 2  
-   ​  ​ g _ = False