C18. Scala Hacks

// for expressions
List(1,2,3).filter(_>2).map(_+1)
 
for (x <- List(1,2,3) if x > 2) yield x + 1
 
for (x <- List(1,2,3);
     y <- List(4,5,6))
      yield (x,y)
 
// List[List[(Int,Int)]]
for (x <- List(1,2,3))
  yield
    for (y <- List(4,5,6))
      yield (x,y)
 
// Cateva lucruri despre colectii
// Despre Vector
 
val letters = Vector("v", "m", "n", "i", "b", "s")
 
// reprezentati ca arbori, cu branching foarte mare
// si adancime foarte mica
 
//
//  <colectie> :<op> <valoare>
//  <valoare> <op>: <colectie>
 
letters :+ "z"
"a" +: letters
 
// cum construim liste de indecsi
(x: Int,y: Int) => x.to(y)
(x: Int,y: Int) => x.until(y)
 
1.to(5).toList
1.until(5).toList
 
// metode care intorc range-uri
 
1.to(100).by(5)
 
// In Scala putem defini operatori infix
 
trait Nat {
  def +(n: Nat): Nat
  def -(n: Nat): Nat
  def unary_~ : Nat
}
 
case object Zero extends Nat{
  override def +(n: Nat): Nat = n
  override def -(n: Nat): Nat = Zero
  override def unary_~ : Nat = Succ(Zero)
}
 
case class Succ(m: Nat) extends Nat{
  // Succ(m) + n =
  // Succ(m + n)
  // m.add(Succ(n)) - POSIBIL
  override def +(n: Nat): Nat = Succ(m + n)
 
  // Succ(m) - n = ...
  override def -(n: Nat): Nat =
    n match {
      case Zero => Succ(m)
      // Succ(m) - Succ(n) = m - n
      case Succ(k) => m - k
    }
 
  override def unary_~ : Nat = Zero
}
 
// DACA IN SCALA AVEM O EXPRESIE DE FORMA
// <obiect>.<functie>(<param>)
// poate fi scrisa, echivalent, si:
// <obiect> <functie> <param>
 
1.to(5)
1 to 5
1.to(100).by(5)
1 to 100 by 5
 
List(1,2,3).take(5)
 
List(1,2,3) take 5
 
~Zero
~Succ(Succ(Zero))
Succ(~Succ(Zero))
 
// - Maps (o colectie)
// - o mapare de la o serie de chei, la una de valori
 
val gradebook: Map[String,Int] =
  Map("John" -> 5)
 
gradebook + ("Mike" -> 5)
 
gradebook.map(p => (p._2, p._1))
 
// cum accesam elemente dintr-un map:
gradebook("John")
 
// valori care nu exista intr-un map?
 
//gradebook("Matei")
 
/* Optiuni: */
if(gradebook.contains("Matei")) gradebook("Matei")
else 0
 
val g2 = gradebook.withDefaultValue(0)
 
/*
trait Option[A]
case class None[A]() extends Option[A]
case class Some[A](value: A) extends Option[A]
 */
 
def head(l: List[Int]): Option[Int] =
  l match{
    case Nil => None
    case x :: _ => Some(x)
   }
 
//gradebook.getOrElse("Matei",)
 
type State = Int
case class Automat(states: Int,
                   transitions: Map[(Int,Char),Int]){
 
  def delta: Map[(Int,Char),Int] =
    transitions.withDefaultValue(-1)
 
  def isFinal(state: Int): Boolean =
    state == states - 1
 
  def addTransition(c: Char, si: Int, sf: Int): Automat =
    Automat(states,transitions + ((si,c) -> sf))
 
  def accepted(w: String): Boolean =
    isFinal(w.toList.foldLeft(0)((st,c)=>delta((st,c))))
 
}