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> |