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/08 15:35]
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)
  
-==== 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> 
 +def drop(n: Int, l: List[Int]): List[Int] = ??? 
 +//​drop(3,​List(1,​2,​3,​4,​5)) = List(4,5) 
 +</​code>​
  
-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.+**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 true. The 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>​
  
-==== Filter ====+**4.1.5.** Write a function which uses a predicate to partition (split) a list. 
 +<code scala> 
 +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>​
  
-The function ​''​filter :: (a -> Bool) -> [a] -> [a]'' ​takes as parameter:​ +==== 4.2. Gradebooks ==== 
-  * a **predicate** (or condition) of type ''​(a -> Bool)''​ +More general implementation of ''​taken''​''​dropn'' ​and ''​part'' ​are already implemented in Scala and can be used as member functions of lists. Examples are shown below: 
-  * a list of elements of type ''​a''​+<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>​
  
-It returns: +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: 
-  * a list of filtered elements using the predicate.+<code scala> 
 +val gradebook = List(("​G",​3),​ ("​F",​ 10), ("​M",​6),​ ("​P",​4)) 
 +</​code> ​
  
-4.1.4. Write function which removes all strings which are equal to the empty string.+To make the type signatures more legible, we can introduce type aliases in Scala: 
 +<code scala> 
 +type Gradebook = List[(String,​Int)] //the type Gradebook now refers to list of pairs of String and Int 
 +</​code>​ 
 +Add this type alias to your code before solving ​the following exercises.
  
-4.1.5. Write a function which takes a list of strings and returns only those which start with capital.+**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> 
 +def increment(g:​ Gradebook): Gradebook = 
 +  g.map(???)  
 +</​code>​
  
-==== Foldr ====+**4.2.2.** Find the average grade from a gradebook. You must use ''​foldRight''​. 
 +<code scala> 
 +def average(g: Gradebook): Double ​??? 
 +</​code>​
  
-The function ''​foldr''​ has type ''​(a -> b -> b) -> b -> [a] -> b''​. It takes as parameter:​ +**4.2.3.** Write function which takes a gradebook and returns the percentage ​of failed vs. passed students, as pair (x,y). 
-  ​**binary** operation ''​-> b -> b''​. It takes a "​list"​ element ​of type ''​a''​and an **accumulator** of type ''​b''​ and returns an element of type ''​b''​ +<code scala> 
-  * an **accumulator** ​(or initial valueof type ''​b''​ +def percentage(g: Gradebook): (Double,​Double) = ??? 
-  * a list with elements of type ''​a''​+</​code>​
  
-It returns: +**4.2.4.** Write a function which takes a gradebook and returns the list of names which have passedUse filter and map from Scala. 
-  ​**folded** (or reduced) value of type ''​b''​.+<code scala> 
 +def pass(g: Gradebook): List[String] = ??? 
 +</​code>​
  
-Example+**4.2.5.** Implement merge-sort (in ascending order) over gradebooks
-<​code ​haskell+<​code ​scala
-foldr (*0 [1,​2,​3] ​1 * (2 * (3 * 0))+def mergeSort(l: Gradebook): Gradebook ​
 +   def merge(u: Gradebook, v: Gradebook): Gradebook = ??? 
 +   ??? 
 +}
 </​code>​ </​code>​
  
-4.1.6. Write a function using foldr which computes the product of a list of integers. +**4.2.6** Write a function which takes a gradebook ​and reports all passing students in **descending** order of their grade
- +<​code ​scala
-4.1.7. Write a function which computes the maximum of a list of **positive** integers using foldr. +def honorsList(g: Gradebook): List[String] = ???
- +
-4.1.8. ​Write a function which concatenates a list of strings using foldr. +
- +
-==== Foldl ==== +
- +
-The function ''​foldl''​ has type ''​(b -> a -> b) -> b -> [a] -> b''​. It takes as parameter:​ +
-  * **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 value) ​of type ''​b''​ +
-  * a list with elements of type ''​a''​ +
- +
-It returns: +
-  * a **folded** (or reduced) value of type ''​b''​. +
- +
-Unlike foldr, foldl reduces element in a different order: +
-Example: +
-<​code ​haskell+
-foldl (*[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.1.10. Write a function which uses foldl to implement the reversal of a list. 
- 
- 
-==== zipWith ==== 
- 
-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? 
- 
- 
-