diff --git a/.idea/compiler.xml b/.idea/compiler.xml index 720822e..ecfa399 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,8 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/scala_compiler.xml b/.idea/scala_compiler.xml new file mode 100644 index 0000000..84c8c19 --- /dev/null +++ b/.idea/scala_compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index c1ec217..dafdb24 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ 1.0 - + scala diff --git a/scala/pom.xml b/scala/pom.xml new file mode 100644 index 0000000..812e02d --- /dev/null +++ b/scala/pom.xml @@ -0,0 +1,75 @@ + + + 4.0.0 + org.gym.fp + scala + 1.0 + + + 2.13.0 + + + + + scala-tools.org + Scala-Tools Maven2 Repository + http://scala-tools.org/repo-releases + + + + + + scala-tools.org + Scala-Tools Maven2 Repository + http://scala-tools.org/repo-releases + + + + + + org.scala-lang + scala-library + ${scala.version} + + + junit + junit + 4.11 + test + + + + + src/main/scala + src/test/scala + + + org.scala-tools + maven-scala-plugin + + + + compile + testCompile + + + + + ${scala.version} + + + + + + + + org.scala-tools + maven-scala-plugin + + ${scala.version} + + + + + diff --git a/scala/src/main/scala/org/gym/fp/App.scala b/scala/src/main/scala/org/gym/fp/App.scala new file mode 100644 index 0000000..02fe7fa --- /dev/null +++ b/scala/src/main/scala/org/gym/fp/App.scala @@ -0,0 +1,215 @@ +package org.gym.fp + +import java.io.File +import java.nio.CharBuffer + +import scala.collection._ + +object App { + + def main(args: Array[String]): Unit = { + doOperationsOnTuples() + doHighOrderFunctions() + doPatternMatching() + doInheritance() + } + + def doOperationsOnTuples(): Unit = { + // definire una tupla + val tupla = (1, "Hello", true) // può essere di vari tipi + println(tupla) + + // Destrutturare una tupla + val (number, greeting, isValid) = tupla + println(s"$number, $greeting, $isValid") + + // Funzione che prende come argomento una tupla di (Int, String, Boolean) + def printTuple(t: (Int, String, Boolean)): Unit = println(s"Da funzione printTuple: $t") + + printTuple(tupla) + + // Pattern matching su lista di tuple + val planets = List( + ("Mercury", 57.9), ("Venus", 108.2), ("Earth", 149.2), + ("Mars", 227.9), ("Jupiter", 778.3) + ) + + planets.foreach { + case ("Earth", distance) => + println(s"Our planet is $distance million kilometers from the sun") + case _ => + } + + // Enumerazione + object Planet extends Enumeration { + type Planet = Value + val Mercury, Venus, Earth, Mars, Saturn, Jupiter, Uranus, Neptune = Value + } + + import Planet._ + val planets2 = Set( + (Mercury, 57.9), (Venus, 108.2), (Earth, 149.2), + (Mars, 227.9), (Jupiter, 778.3) + ) + + planets2.foreach { + case (Jupiter, distance) => + println(s"Our planet is $distance million kilometers from the sun") + case _ => + } + + } + + def doHighOrderFunctions(): Unit = { + + object SalaryRaiser { + private def promotion(salaries: List[Double], promotionsFunction: Double => Double): List[Double] = + salaries.map(promotionsFunction) + + def smallPromotion(salaries: List[Double]): List[Double] = + promotion(salaries, salary => salary * 1.1) + + def greatPromotion(salaries: List[Double]): List[Double] = + promotion(salaries, salary => salary * Math.log(salary)) + + def hugePromotion(salaries: List[Double]): List[Double] = + promotion(salaries, salary => salary * salary) + } + + case class Person(val name: String, val salary: Double) + + val promotions = List(Person("Giacomo", 20000), Person("Mario", 30000)).map(_.salary) + SalaryRaiser.smallPromotion(promotions).foreach(println) + + def urlBuilder(ssl: Boolean, domainName: String): (String, String) => String = { + val schema = if (ssl) "https://" else "http://" + (endpoint: String, query: String) => s"$schema$domainName/$endpoint?$query" + } + + val domainName = "www.example.com" + + def getURL = urlBuilder(ssl = true, domainName) + + val endpoint = "users" + val query = "id=1" + val url = getURL(endpoint, query) + println(url) + } + + def doPatternMatching(): Unit = { + // Pattern Matching con le case class + abstract class Notification + case class Email(sender: String, title: String, body: String) extends Notification + case class SMS(caller: String, message: String) extends Notification + case class VoiceRecording(contactName: String, link: String) extends Notification + + def showNotification(notification: Notification): String = { + notification match { + case Email(sender, title, _) => + s"You got an email from $sender with title: $title" + case SMS(number, message) => + s"You got an SMS from $number! Message: $message" + case VoiceRecording(name, link) => + s"You received a Voice Recording from $name! Click the link to hear it: $link" + } + } + + val someSMS = SMS("12345", "Are you there?") + val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123") + + println(showNotification(someSMS)) + println(showNotification(someVoiceRecording)) + + // Aggiungo un Pattern Guard, cioè una condizione addizionale per cui vale quel matching + def showImportantNotification(notification: Notification, importantPeopleInfo: Seq[String]): String = { + notification match { + case Email(sender, _, _) if importantPeopleInfo.contains(sender) => + "You got an email from special someone!" + case SMS(number, _) if importantPeopleInfo.contains(number) => + "You got an SMS from special someone!" + case other => + showNotification(other) + } + } + + val importantPeopleInfo = Seq("867-5309", "jenny@gmail.com") + + val importantEmail = Email("jenny@gmail.com", "Drinks tonight?", "I'm free after 5!") + val importantSms = SMS("867-5309", "I'm here! Where are you?") + + println(showImportantNotification(someSMS, importantPeopleInfo)) + println(showImportantNotification(someVoiceRecording, importantPeopleInfo)) + println(showImportantNotification(importantEmail, importantPeopleInfo)) + println(showImportantNotification(importantSms, importantPeopleInfo)) + + } + + def doInheritance(): Unit = { + class Customer(val name: String, val address: String) extends Ordered[Customer] { + val total: Double = 0.0 + + override def compare(that: Customer): Int = this.name.compareTo(that.name) + + override def toString: String = s"$name is located at $address" + } + class DiscountedCustomer(name: String, address: String) extends Customer(name, address) + + trait Readable { + def read(buffer: CharBuffer): Int + } + class FileReader(file: File) extends Readable with AutoCloseable { + override def read(buffer: CharBuffer): Int = { + val linesRead: Int = 0 + return linesRead + } + + override def close(): Unit = ??? + } + + trait Sortable[A <: Ordered[A]] extends Iterable[A] { + def sort: Seq[A] = { + this.toList.sorted + } + } + + class Customers extends Sortable[Customer] { + private val customers = mutable.Set[Customer]() + + def add(customer: Customer) = customers.add(customer) + + override def iterator: Iterator[Customer] = customers.iterator + } + class CustomersSortableBySpend extends Customers { + override def sort: Seq[Customer] = { + this.toList.sorted((a: Customer, b: Customer) => b.total.compare(a.total)) + } + } + + val customers = new Customers() + customers.add(new Customer("Fred Jones", "8 Tuna Lane")) + customers.add(new Customer("Velma Dinkley", "316 Circle Drive")) + customers.add(new Customer("Daphne Blake", "101 Easy St")) + customers.add(new Customer("Norville Rogers", "1 Lane")) + println(customers.sort) + + trait Counter { + protected var count: Int // abstract field + + def increment() + } + + class IncrementByOne extends Counter { + override protected var count: Int = 0 + + override def increment(): Unit = count += 1 + } + + class ExponentialIncrementer(rate: Int) extends Counter { + override protected var count: Int = 1 + + override def increment(): Unit = count *= rate + + } + } + +} diff --git a/scala/src/test/scala/org/gym/fp/AppTest.scala b/scala/src/test/scala/org/gym/fp/AppTest.scala new file mode 100644 index 0000000..bc965f5 --- /dev/null +++ b/scala/src/test/scala/org/gym/fp/AppTest.scala @@ -0,0 +1,14 @@ +package org.gym.fp + +import org.junit._ +import Assert._ + +@Test +class AppTest { + + @Test + def testOK() = assertTrue(true) + +} + +