Differences

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

Link to this comparison view

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