feat: add ex3
add parametrized type, union, enum, alias
This commit is contained in:
		| @@ -6,10 +6,33 @@ trait Person { | |||||||
|   val name: String |   val name: String | ||||||
| } | } | ||||||
|  |  | ||||||
| case class Artist(name: String) extends Person | case class Singer(name: String) extends Person | ||||||
|  |  | ||||||
| case class Writer(name: String) extends Person | case class Writer(name: String) extends Person | ||||||
|  |  | ||||||
| case class Producer(name: String) extends Person | case class Producer(name: String) extends Person | ||||||
| class Album(title: String, label: String) |  | ||||||
|  | // The parametrized type Artist can be a Singer, a Writer or a Producer | ||||||
|  | // They do a different creation action | ||||||
|  | class Artist[A <: Person](val person: A) { | ||||||
|  |   def create(): String = { | ||||||
|  |     person match { | ||||||
|  |       case s: Singer => s"${s.name} sing" | ||||||
|  |       case w: Writer => s"${w.name} write" | ||||||
|  |       case p: Producer => s"${p.name} produce" | ||||||
|  |       case _ => s"${person.name} create" | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Defined a MusicGender as en enum | ||||||
|  | enum MusicGenre: | ||||||
|  |   case Rock, Soul, Blues, Folk, Funk, Reggae, HipHop, NewWave, Electro, Metal | ||||||
|  |  | ||||||
|  | // Define an Album with a union between a String and a MusicGenre | ||||||
|  | class Album(title: String, label: String, genre: String|MusicGenre) | ||||||
|  |  | ||||||
| class Streak(val s: String) { | class Streak(val s: String) { | ||||||
|   val streak: Option[Int] = { |   val streak: Option[Int] = { | ||||||
|     val regex = "\\d+".r |     val regex = "\\d+".r | ||||||
| @@ -23,8 +46,9 @@ class Streak(val s: String) { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| class Position(val p: String) { | class Position(val p: String) { | ||||||
|   val position: Option[Int] = { |   val pos: Option[Int] = { | ||||||
|     val regex = "\\d+".r |     val regex = "\\d+".r | ||||||
|     regex.findFirstIn(p) match { |     regex.findFirstIn(p) match { | ||||||
|       case Some(value) => Some(Integer.parseInt(value)) |       case Some(value) => Some(Integer.parseInt(value)) | ||||||
| @@ -33,15 +57,24 @@ class Position(val p: String) { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // Defined a type alias Rank which is a tuple of Streak and Position | ||||||
|  | // Streak and Position are linked together, it's why there are regrouped in the Rank type alias | ||||||
|  | type Rank = (Streak, Position) | ||||||
|  |  | ||||||
|  | // Defined an intersection type of Artist & Writer & Producer | ||||||
|  | // Defined with an alias : God | ||||||
|  | // It's a way to define a type that is a combination of other types | ||||||
|  | // If an Artist is also a Writer and a Producer, it's basically a God of the music | ||||||
|  | type God = Singer & Writer & Producer | ||||||
|  |  | ||||||
| class Song( | class Song( | ||||||
|   val title: String, |   val title: String, | ||||||
|   val description: Option[String], |   val description: Option[String], | ||||||
|   val artist: List[Artist], |   val singer: List[Artist[Singer]], | ||||||
|   val writer: List[Writer], |   val writer: List[Artist[Writer]], | ||||||
|   val producer: List[Producer], |   val producer: List[Artist[Producer]], | ||||||
|   val album: Option[Album], |   val album: Option[Album], | ||||||
|   val streak: Streak, |   val rank: Rank | ||||||
|   val position: Position |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -50,12 +83,27 @@ case class TopSongs(songs: List[Song] = List()) { | |||||||
|     TopSongs(song :: songs) |     TopSongs(song :: songs) | ||||||
|   } |   } | ||||||
|   def printSongs(): Unit = { |   def printSongs(): Unit = { | ||||||
|     songs.foreach(song => println( |     songs.foreach(song => { | ||||||
|       s"${song.title} by ${song.artist.map(_.name).mkString(", ")} " + |       val title = song.title | ||||||
|         s"produced by ${song.producer.map(_.name).mkString(", ")} " + |       val singer = song.singer | ||||||
|         s"spent ${song.streak.streak.getOrElse("no")} weeks " + |       val producers = song.producer.map(_.create()).mkString(", ") | ||||||
|         s"on the charts on Pos. ${song.position.position.getOrElse("NA")}" |       val streak = song.rank._1.streak.getOrElse("no") | ||||||
|     )) |       val pos = song.rank._2.pos.getOrElse("NA") | ||||||
|  |  | ||||||
|  |       if (singer.exists(a => { | ||||||
|  |         a.isInstanceOf[God] | ||||||
|  |       })) { | ||||||
|  |         println(s"$title by God ${singer.map(_.person.name).mkString(", ")} spent $streak weeks on the charts on Pos. $pos") | ||||||
|  |       } else { | ||||||
|  |         println( | ||||||
|  |           s"$title by ${singer.map(_.person.name).mkString(", ")}. " + | ||||||
|  |             s"$producers this song that " + | ||||||
|  |             s"spent $streak weeks " + | ||||||
|  |             s"on the charts on Pos. $pos" | ||||||
|  |         ) | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |     }) | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -66,15 +114,22 @@ case class TopSongs(songs: List[Song] = List()) { | |||||||
|   val reader = CSVReader.open(new File("src/main/resources/songs.csv")) |   val reader = CSVReader.open(new File("src/main/resources/songs.csv")) | ||||||
|   val allRows = reader.allWithHeaders() |   val allRows = reader.allWithHeaders() | ||||||
|   for (row <- allRows) { |   for (row <- allRows) { | ||||||
|  |     val title = row("title") | ||||||
|  |     val description = row("description") | ||||||
|  |     val singer = List(Artist[Singer](Singer(row("artist")))) | ||||||
|  |     val writers = List(Artist[Writer](Writer(row("writers")))) | ||||||
|  |     val producers = List(Artist[Producer](Producer(row("producer")))) | ||||||
|  |     val album = Some(Album(row("appears on"), "NA", null)) | ||||||
|  |     val rank = (Streak(row("streak")), Position(row("position"))) | ||||||
|  |  | ||||||
|     val s = Song( |     val s = Song( | ||||||
|       title = row("title"), |       title = title, | ||||||
|       description = Some(row("description")), |       description = Some(description), | ||||||
|       artist = List(Artist(row("artist"))), |       singer = singer, | ||||||
|       writer = List(Writer(row("writers"))), |       writer = writers, | ||||||
|       producer = List(Producer(row("producer"))), |       producer = producers, | ||||||
|       album = Some(Album(row("appears on"), "NA")), |       album = album, | ||||||
|       streak = Streak(row("streak")), |       rank = rank | ||||||
|       position = Position(row("position")) |  | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     // add the song to the TopSongs object |     // add the song to the TopSongs object | ||||||
| @@ -82,5 +137,7 @@ case class TopSongs(songs: List[Song] = List()) { | |||||||
|   } |   } | ||||||
|   reader.close() |   reader.close() | ||||||
|  |  | ||||||
|  |   val foo: Boolean = topSongs.songs.exists(s => s.rank._1.streak.contains(1)) | ||||||
|  |  | ||||||
|   // print the songs |   // print the songs | ||||||
|   topSongs.printSongs() |   topSongs.printSongs() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user