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
fp:lab04 [2021/04/01 12:28]
lfa
fp:lab04 [2022/05/15 23:54] (current)
vbadoiu old revision restored (2022/03/25 10:15)
Line 1: Line 1:
-====== 4. Higher order functions ======+===== 4. Lists in Scala =====
  
-===== 4.1. MapfoldlfoldrfilterzipWith =====+Objectives:​ 
 +  * get familiar with **pattern matching** listsas well as common list operations from Scala and how they work 
 +  * get familiar with common **higher-order functions** over lists (partitionmapfoldRightfoldLeft, filter)
  
-==== Map ==== +==== 4.1. Common list operations ​====
-The function ''​map''​ has signature: ''​(a->​b) -> [a] -> [b]''​. It takes as parameter:​ +
-   - a **transformer** function ''​f :: a->​b''​ +
-   - a list of objects of type ''​a''​+
  
-It returns+**4.1.1.** Write a function which returns ​true if a list of integers has at least k elements. Use patterns. 
-   ​- ​a list of transformed objects of type ''​b''​+<code scala> 
 +def atLeastk(k: Int, l: List[Int]): Boolean = 
 +  if (k == 0) ??? 
 +  else ??? 
 +  } 
 +</​code>​
  
-4.1.1. Write a function which takes a list of integers and adds 4 to **each element**.+**4.1.2.** Write a function which returns the first ''​n''​ elements from given list. The function should not be implemented as tail-recursive. 
 +<code scala> 
 +def take(n: Int, l: List[Int]): List[Int] = ??? 
 +//​take(3,​List(1,​2,​3,​4,​5)) = List(1,​2,​3) 
 +</​code>​
  
-4.1.2. Write a function which takes a list of strings and adds a whitespace at the **beginning** of each string. +**4.1.3.** Write a function which //​drops// ​the first ''​n''​ elements ​from given list. The function ​should not be implemented as tail-recursive
- +<code scala> 
-4.1.3. Write a function which takes a value k, a list of **strings** and returns a list with the first k characters of each string. +def drop(n: Int, l: List[Int]): List[Int= ??? 
- +//drop(3,List(1,2,3,4,5)= List(4,5) 
-==== Filter ==== +</​code>​
- +
-The function ​''​filter :: (a -> Bool) -> [a] -> [a]'' ​takes as parameter:​ +
-  * a **predicate** (or condition) of type ''​(a -> Bool)''​ +
-  * a list of elements ​of type ''​a''​ +
- +
-It returns: +
-  * a list of filtered elements using the predicate. +
- +
-4.1.4. Write a function ​which removes all strings which are equal to the empty string+
- +
-4.1.5. Write a function which takes a list of strings and returns only those which start with a capital. +
- +
-==== Foldr ==== +
- +
-The function ''​foldr''​ has type ''​(a -> b -> b-> b -> [a-> b''​. It takes as parameter: +
-  * a **binary** operation ''​a -> b -> b''​. It takes a "​list"​ element of type ''​a''​and an **accumulator** of type ''​b''​ and returns an element of type ''​b''​ +
-  * an **accumulator** ​(or initial valueof type ''​b''​ +
-  * a list with elements of type ''​a''​ +
- +
-It returns: +
-  * a **folded** ​(or reducedvalue of type ''​b''​.+
  
-Example+**4.1.4.** Write a function which takes a predicate ''​pInt => Boolean'',​ a list ''​l''​ and returns a sublist of ''​l''​ containing those elements for which ''​p''​ is true. The function should be **curried**. 
-<​code ​haskell+<​code ​scala
-foldr (*[1,2,31 * (2 * (3 * 0))+def takeP(p: Int => Boolean)(l: List[Int]): List[Int] = ??? 
 +//takeP(_%2 == 0)(List(1,2,3,​4,​5,​6)) ​List(2,4,6)
 </​code>​ </​code>​
  
-4.1.6Write a function using foldr which computes the product of a list of integers. +**4.1.5.** Write a function which uses a predicate to partition (split) ​a list. 
- +<code scala> 
-4.1.7. Write a function which computes the maximum of a list of **positive** integers using foldr. +def part(p: Int => Boolean)(l: List[Int])(List[Int]List[Int]= ??? 
- +// part(_%2 == 0)(List(1,2,3,​4,​5,​6)) ​= (List(2,​4,​6),​List(1,3,5))
-4.1.8. ​Write a function which concatenates ​a list of strings using foldr+
- +
-==== Foldl ==== +
- +
-The function ''​foldr''​ has type ''​(b -a -> b-> b -> [a-> b''​. It takes as parameter: +
-  * a **binary** operation ''​b -> a -> b''​. It takes an **accumulator** of type ''​b''​a "​list"​ element of type ''​a''​ and returns an element of type ''​b''​ +
-  * an **accumulator** (or initial valueof type ''​b''​ +
-  * a list with elements of type ''​a''​ +
- +
-It returns: +
-  * a **folded** ​(or reducedvalue of type ''​b''​. +
- +
-Unlike foldr, foldl reduces element in a different order: +
-Example: +
-<code haskell>​ +
-foldl (*) 0 [1,2,3= ((0 * 1) * 2* 3+
 </​code>​ </​code>​
  
-4.1.9. Write a function which uses foldl to check if an element is member of a list. +==== 4.2. Gradebooks ​==== 
- +More general implementation of ''​taken''​, ''dropn'' ​and ''​part''​ are already implemented in Scala and can be used as member ​functions ​of listsExamples are shown below
-4.1.10. Write a function which uses foldl to implement the reversal of a list. +<​code ​scala
- +val l = List(1,2,3,4,5,6,7,8,9) 
- +l.take(3) 
-==== zipWith ​==== +l.drop(3) 
- +l.partition(_%2 == 0)
-4.1.11. Use ''​ghci> :t zipWith'' ​to inspect the type of ''​zipWith''​. Think about a possible example to run this function. What does it do? +
- +
- +
-===== 4.2. Processing using higher-order ​functions ​===== +
- +
-The following is an input testYou can add more examples to it+
-<​code ​haskell+
-l = ["​matei@gmail.com"​"​mihai@gmail.com"​"​tEst@mail.com"​"​email@email.com"​"​short@ax.ro"]+
 </​code>​ </​code>​
  
-Use ''​map'',​ ''​foldr''​/''​foldl''​, instead of recursive functionsWherever possibleuse functional composition and closures.+In what follows, we shall encode a gradebook as a list of pairs ''​(<​name>,<​grade>​)'', ​where ''​<​name>​'' ​is a String and ''​<​grade>​'' ​is an IntExample: 
 +<code scala> 
 +val gradebook = List(("​G"​,3), ("​F",​ 10), ("​M",​6),​ ("​P",​4)) 
 +</​code> ​
  
-4.2.1. Remove uppercases from emails. (Do **not** use recursion). ​To be able to use character functions from the libraryadd ''​import Data.Char''​ at the beginning of the program. Use the Internet to find the appropriate character function. +To make the type signatures more legiblewe can introduce type aliases in Scala: 
- +<​code ​scala
-<​code ​haskell+type Gradebook = List[(String,​Int)] //the type Gradebook now refers to list of pairs of String and Int
--- write this function as closure +
-rem_upper = +
 </​code>​ </​code>​
 +Add this type alias to your code before solving the following exercises.
  
-4.2.2. Write a function which removes emails longer than given size. Write the function as a **functional closure**. Use anonymous functions in your implementation,​ then think about how you can replace them by a functional composition of more basic functions. **Hint:** Write your code in steps. Start with the basic ideathen think about how you can write it better ​and cleaner. +**4.2.1.** Write a function which adds one point  to all students which have passing grade (>= 5), and leaves all other grades unchanged
- +<​code ​scala
-<​code ​haskell+def increment(gGradebook)Gradebook = 
-longer ​:: Int -> [String] -> [String] +  ​g.map(???​) ​
-longer x = +
 </​code>​ </​code>​
  
-4.2.3Count the number of emails longer than 12 characters. Use fold, anonymous functions and functional composition+**4.2.2.** Find the average grade from gradebook. You must use ''​foldRight''​
-<​code ​haskell+<​code ​scala
-howmany ​=+def average(g: Gradebook): Double ​???
 </​code>​ </​code>​
  
-4.2.4Split the list between first names and email domainsWhat ingredients ​(auxiliary functionsare necessary? Use either a fold or a tail-recursive function in your implementation+**4.2.3.** Write a function which takes a gradebook ​and returns the percentage of failed vspassed students, as a pair (x,y). 
-<​code ​haskell+<​code ​scala
-names_emails ​:: [String] -> [[String]] +def percentage(gGradebook)(Double,​Double) ​???
-names_emails ​=+
 </​code>​ </​code>​
  
-4.2.5Identify ​the list of the employed domain ​names (e.g. ''​gmail.com''​). Remove duplicates. Use no recursion ​and no additional prelude function apart from ''​head''​ and ''​tail''​. **Hint** think about the sequence of basic operations you want to perform and assemble them using functional composition+**4.2.4.** Write a function which takes a gradebook and returns ​the list of names which have passed. Use filter ​and map from Scala
-<​code ​haskell+<​code ​scala
-domains ​:: [String] ​-> [String] +def pass(gGradebook)List[String] = ???
-domains ​=+
 </​code>​ </​code>​
  
-(!) 4.2.6. In some previous exercise you have, most likely, implemented a split function using ''​foldr''​. Implement one with ''​foldl''​. **Hint:** use an example together with the ''​foldl''​ implementation to figure out what the accumulator should do. +**4.2.5.** Implement merge-sort (in ascending order) over gradebooks
- +<​code ​scala
-<​code ​haskell+def mergeSort(lGradebook)Gradebook = { 
-splitl ​:: String -> [String] +   def merge(u: Gradebook, v: Gradebook): Gradebook ​??? 
-splitl ​+   ??? 
 +}
 </​code>​ </​code>​
  
-4.2.7. Write a function which extracts the domains from emails, without the dot part. (e.g. ''​gmail''​). Generalise the previous function ''​splitl''​ to ''​splitBy::​ Char -> String -> [String]'', ​and use it each time necessary, ​in your implementation. ​**Hint**: Wherever you want to mix pattern matching with guards, start with the patterns first. +**4.2.6** Write a function which takes a gradebook ​and reports all passing students ​in **descending** order of their grade
- +<​code ​scala
-<​code ​haskell+def honorsList(gGradebook)List[String] = ???
-domain ​:: [String] ​-> [String] +
-domain ​=+
 </​code>​ </​code>​
-