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 11:53]
pdmatei
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)
  
 +==== 4.1. Common list operations ====
  
-===== 4.2Processing using higher-order functions =====+**4.1.1.** Write a function which returns true if a list of integers has at least k elements. Use patterns. 
 +<code scala> 
 +def atLeastk(k: Int, l: List[Int]): Boolean ​= 
 +  if (k == 0) ??? 
 +  else ??? 
 +  } 
 +</​code>​
  
-The following is an input testYou can add more examples to it: +**4.1.2.** Write a function which returns the first ''​n''​ elements from a given list. The function should not be implemented as tail-recursive
-<​code ​haskell+<​code ​scala
-["​matei@gmail.com"​"​mihai@gmail.com"​"​tEst@mail.com"​"​email@email.com"​"​short@ax.ro"​]+def take(n: Int, l: List[Int]): List[Int] = ??? 
 +//take(3,List(1,2,3,4,5)) = List(1,2,3)
 </​code>​ </​code>​
  
-Use ''​map'',​ ''​foldr''​/''​foldl''​, instead of recursive ​functionsWherever possibleuse functional composition and closures.+**4.1.3.** Write a function which //drops// the first ''​n'' ​elements from a given list. The function should not be implemented as tail-recursive. 
 +<code scala> 
 +def drop(n: Intl: List[Int]): List[Int] = ??? 
 +//​drop(3,​List(1,​2,​3,​4,​5)) = List(4,5) 
 +</​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 programUse the Internet to find the appropriate character ​function.+**4.1.4.** Write a function which takes a predicate ''​p:​ Int => Boolean''​a list ''​l'' ​and returns a sublist ​of ''​l''​ containing those elements for which ''​p''​ is trueThe function ​should be **curried**. 
 +<code scala> 
 +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 ​haskell+**4.1.5.** Write a function which uses a predicate to partition (split) a list. 
--- write this function as a closure +<​code ​scala
-rem_upper ​+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))
 </​code>​ </​code>​
  
-4.2.2. Write a function which removes emails longer than a 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 stepsStart with the basic ideathen think about how you can write it better ​and cleaner.+==== 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: 
 +<code scala> 
 +val l = List(1,​2,​3,​4,​5,​6,​7,​8,​9) 
 +l.take(3) 
 +l.drop(3) 
 +l.partition(_%2 == 0) 
 +</​code>​ 
 + 
 +In what followswe 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> ​
  
-<​code ​haskell+To make the type signatures more legible, we can introduce type aliases in Scala: 
-longer :: Int -> [String] ​-> [String+<​code ​scala
-longer x = +type Gradebook = List[(String,Int)//the type Gradebook now refers to a list of pairs of String ​and Int
 </​code>​ </​code>​
 +Add this type alias to your code before solving the following exercises.
  
-4.2.3Count the number of emails longer than 12 characters. Use foldanonymous functions ​and functional composition+**4.2.1.** Write function which adds one point  to all students which have a passing grade (>= 5), and leaves all other grades unchanged
-<​code ​haskell+<​code ​scala
-howmany ​=+def increment(g:​ Gradebook): Gradebook ​= 
 +  g.map(???​) ​
 </​code>​ </​code>​
  
-4.2.4Split the list between first names and email domains. What ingredients (auxiliary functions) are necessary? Use either a fold or tail-recursive function in your implementation+**4.2.2.** Find the average grade from gradebook. You must use ''​foldRight''​
-<​code ​haskell+<​code ​scala
-names_emails ​:: [String] -> [[String]] +def average(gGradebook)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.3.** Write a function which takes a gradebook and returns ​the percentage ​of failed vs. passed students, as a pair (x,y). 
-<​code ​haskell+<​code ​scala
-domains ​:: [String] -> [String] +def percentage(gGradebook)(Double,​Double) ​???
-domains ​=+
 </​code>​ </​code>​
  
-(!) 4.2.6In some previous exercise you have, most likely, implemented ​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.4.** Write a function ​which takes a gradebook and returns the list of names which have passedUse filter and map from Scala
- +<​code ​scala
-<​code ​haskell+def pass(gGradebook)List[String] = ???
-splitl ​:: String -> [String] +
-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.5.** Implement merge-sort ​(in ascending orderover gradebooks
- +<​code ​scala
-<​code ​haskell+def mergeSort(lGradebook)Gradebook = { 
-domain ​:: [String] -> [String] +   def merge(u: Gradebook, v: Gradebook): Gradebook ​??? 
-domain ​=+   ??? 
 +}
 </​code>​ </​code>​
  
 +**4.2.6** Write a function which takes a gradebook and reports all passing students in **descending** order of their grade.
 +<code scala>
 +def honorsList(g:​ Gradebook): List[String] = ???
 +</​code>​