Differences
This shows you the differences between two versions of the page.
| fp2023:lec06 [2023/04/04 13:38] pdmatei created | fp2023:lec06 [2023/04/04 13:49] (current) pdmatei | ||
|---|---|---|---|
| Line 2: | Line 2: | ||
| <code scala> | <code scala> | ||
| + | /* | ||
| + | Topic 1. Liste (din Scala). | ||
| + | */ | ||
| + | |||
| + | val l = List(1,2,3) | ||
| + | //Cons(1,Cons(2,Cons(3,Void))) | ||
| + | |||
| + | 1 :: 2 :: 3 :: Nil | ||
| + | |||
| + | List(1,2,3) match { | ||
| + | case Nil => 0 | ||
| + | case x :: y :: Nil => 2 | ||
| + | case x :: y :: _ => 3 | ||
| + | case x :: xs => 1 | ||
| + | } | ||
| + | // listele sunt orientate obiect | ||
| + | l.head // 1 | ||
| + | l.tail // | ||
| + | |||
| + | l.map(_*2) // transformare per element | ||
| + | l.foldRight(0)(_ + _) | ||
| + | // 1 + (2 + (3 + acc))) | ||
| + | |||
| + | l.foldLeft(Nil:List[Int])((acc,x) => x :: acc) | ||
| + | // (acc op 1) op 2) op 3 | ||
| + | |||
| + | val lp = List((1,2), (3,1), (4,4)) | ||
| + | |||
| + | lp.sortBy(_._2) | ||
| + | lp.sortBy(x => x._1 + x._2) | ||
| + | |||
| + | /* notatia infix*/ | ||
| + | |||
| + | trait Nat { | ||
| + | def +(other: Nat): Nat | ||
| + | def -(other: Nat): Nat | ||
| + | } | ||
| + | |||
| + | case object Zero extends Nat { | ||
| + | override def +(other: Nat): Nat = other | ||
| + | override def -(other: Nat): Nat = Zero | ||
| + | } | ||
| + | |||
| + | case class Succ(n: Nat) extends Nat { | ||
| + | override def +(other: Nat): Nat = Succ(n + other) | ||
| + | override def -(other: Nat): Nat = | ||
| + | other match { | ||
| + | case Zero => this | ||
| + | case Succ(np) => n - np | ||
| + | } | ||
| + | } | ||
| + | |||
| + | val x = Succ(Zero) | ||
| + | val y = Succ(Succ(Zero)) | ||
| + | |||
| + | x + y | ||
| + | |||
| + | |||
| + | /* | ||
| + | In Scala, expresia: | ||
| + | |||
| + | token1 token2 token3 se citeste: | ||
| + | token1.token2(token3), cu conditia ca: | ||
| + | token1 sa fie un obiect | ||
| + | token2 sa fie o functie membru a clasei obiectului resp. | ||
| + | token3 sa fie un parametru | ||
| + | */ | ||
| + | |||
| + | x.-(y) | ||
| + | x - y | ||
| + | |||
| + | List(1,2,3) map (_+1) | ||
| + | List(1,2,3).map(_+1) | ||
| + | |||
| + | val f = ((x: Int) => x + 1) andThen | ||
| + | (_*2) andThen | ||
| + | (_-1) | ||
| + | |||
| + | f(1) | ||
| + | |||
| + | val emails = | ||
| + | List("matei@gmail.com", "mihai@gmail.com", "ana@gmail.com", "john@yahoo.com", "mary@aol.com", "maria@upb.ro") | ||
| + | |||
| + | /* vrem sa aflam frecventa cu care apare un domeniu in lista de mai sus */ | ||
| + | /* sa zicem ca ne intereseaza frecventa pt domeniul gmail */ | ||
| + | |||
| + | // Cum implementam (abordam) aceasta problema FUNCTIONAL? | ||
| + | |||
| + | "Test".toList | ||
| + | |||
| + | /* | ||
| + | This function will be included later in the final implementation: | ||
| + | |||
| + | def getDomain(email: List[Char]): List[Char] = | ||
| + | email match { | ||
| + | case '@' :: xs => xs | ||
| + | case _ :: xs => getDomain(xs) | ||
| + | } | ||
| + | |||
| + | getDomain("Matei@gmail.com".toList) | ||
| + | */ | ||
| + | type Str = List[Char] | ||
| + | |||
| + | def getFrequencies(emails: List[String]): List[(String,Int)] = { | ||
| + | |||
| + | def getDomain(email: Str): Str = | ||
| + | email match { | ||
| + | case '@' :: xs => xs | ||
| + | case _ :: xs => getDomain(xs) | ||
| + | } | ||
| + | |||
| + | def join(domain: Str): String = | ||
| + | domain.foldRight("")(_ + _) // introducerea unui caracter intr-un string | ||
| + | /* | ||
| + | recursive variant for groupLists. We prefer writing is using foldRight, as below: | ||
| + | def groupLists(l: List[String]): List[List[String]] = | ||
| + | l match { | ||
| + | case Nil => Nil | ||
| + | case x :: xs => { | ||
| + | val r = groupLists(xs) | ||
| + | if (x == r.head.head)  (x :: r.head) :: r.tail | ||
| + | else (x :: Nil) :: r | ||
| + | } | ||
| + | }*/ | ||
| + | def groupLists(l: List[String]): List[List[String]] = | ||
| + | l.foldRight(Nil:List[List[String]])((domain,acc) => | ||
| + | if (acc == Nil) List(domain)::Nil | ||
| + | else if (domain == acc.head.head) (domain :: acc.head) :: acc.tail | ||
| + | else (domain :: Nil) :: acc | ||
| + | ) | ||
| + | |||
| + | // the outer set of parentheses are mandatory, in order to express where does the andThen sequence end | ||
| + | val sequence = | ||
| + | (((l: List[String]) => l.map(_.toList))  // make each String into a Str (List[Char]) | ||
| + | andThen (_.map(getDomain(_)))  // extract the domain from each Str | ||
| + | andThen (_.map(join(_)))  // convert to String back again | ||
| + | andThen (_.sortBy(x => x)) // sort the list of domains | ||
| + | andThen (groupLists(_))  // group identical domains | ||
| + | andThen (_.map(group => (group.head,group.size))))  // transform each group into a frequency pair | ||
| + | |||
| + | sequence(emails) | ||
| + | |||
| + | |||
| + | } | ||
| + | |||
| + | getFrequencies(emails) | ||
| + | |||
| + | |||
| + | /* | ||
| + | def groupLists(l: List[String]): List[List[String]] = | ||
| + | l match { | ||
| + | case x :: Nil => List(x) :: Nil | ||
| + | case x :: xs => { | ||
| + | val r = groupLists(xs) | ||
| + | if (x == r.head.head) (x :: r.head) :: r.tail | ||
| + | else (x :: Nil) :: r | ||
| + | } | ||
| + | } | ||
| + | */ | ||
| + | |||
| + | |||
| </code> | </code> | ||