Differences

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

Link to this comparison view

Next revision
Previous revision
fp2025:lab09 [2026/05/16 22:57]
silviu created
fp2025:lab09 [2026/05/16 23:16] (current)
silviu
Line 9: Line 9:
 *Introduction* *Introduction*
  
-When we define a generic type, for example ''​Box[T]'',​ and we have a types ''​Animal''​ and ''​Dog''​ and ''​Dog extends Animal'',​ the type ''​Shelter[Dog]''​ does not extend type ''​Shelter[Animal]''​. However, sometimes we would like to have a conversion in one direction or the other. For example, consider the following code:+When we define a generic type, for example ''​Shelter[T]'',​ and we have a types ''​Animal''​ and ''​Dog''​ and ''​Dog extends Animal'',​ the type ''​Shelter[Dog]''​ does not extend type ''​Shelter[Animal]''​. However, sometimes we would like to have a conversion in one direction or the other. For example, consider the following code:
  
 <code scala> <code scala>
Line 52: Line 52:
 </​code>​ </​code>​
  
-**9.2.** Modify this type to use the correct variance:+**9.2.** Modify this type to use the correct variance ​to the generic parameter:
  
 <code scala> <code scala>
Line 92: Line 92:
       println(" ​ -> No animals matched this criteria."​)       println(" ​ -> No animals matched this criteria."​)
     } else {     } else {
-      ​matches.foreach(animal => println(s" ​ -> MATCH: ​${animal.name}"))+      println(s" ​ -> There were ${matches.lengthmatches.")
     }     }
 } }
 </​code>​ </​code>​
 +
 +Notice the invariance of the generic parameter, it will come up in the last exercise.
  
 **9.6.** Apply the ''​crossJoinAndFilter''​ method on every possible shelter-predicate combination from the previous exercises, note which ones compile and which none don't. **9.6.** Apply the ''​crossJoinAndFilter''​ method on every possible shelter-predicate combination from the previous exercises, note which ones compile and which none don't.
Line 109: Line 111:
  
  
-**9.7.** Complete the following code and use the proper bound to implement it, start from a shelter for ''​Corgi''​ and then expand it by adding new types of residents:+**9.8.** Complete the following code and use the proper bound to implement it, start from a shelter for ''​Corgi''​ and then expand it by adding new types of residents:
  
 <code scala> <code scala>
Line 115: Line 117:
  
 def saveAnimal[???​T???​](newResident:​ T): Shelter[T] = { def saveAnimal[???​T???​](newResident:​ T): Shelter[T] = {
-    //Create ​a new shelter by adding ​the new resident+    // Returns ​a new Shelter[T] containing the old residents + the new resident
 } }
 </​code>​ </​code>​
  
-**9.8.** Apply the proper generic types to this function and test it, ''​S''​ is the type of residents in the shelter and ''​P''​ is the type to test in the predicate, chose the proper bound:+**9.9.** Apply the proper generic types to this function and test it, ''​S''​ is the type of residents in the shelter and ''​P''​ is the type to test in the predicate, chose the proper bound:
  
 +<code scala>
 def safeCrossJoin[???​](shelter:​ Shelter[S], predicate: Predicate[P]):​ Unit = { def safeCrossJoin[???​](shelter:​ Shelter[S], predicate: Predicate[P]):​ Unit = {
   println(s"​Safely filtering ${shelter.name}:"​)   println(s"​Safely filtering ${shelter.name}:"​)
Line 129: Line 132:
   }   }
 } }
 +</​code>​