===== Curs 5. Liste in Scala ===== // 1 + 2 * 3 trait Expr { def eval(): Int } case class Atom(x: Int) extends Expr { override def eval(): Int = x } case class Add(e1: Expr, e2: Expr) extends Expr { override def eval(): Int = e1.eval() + e2.eval() } case class Mult(e1: Expr, e2: Expr) extends Expr{ override def eval(): Int = e1.eval() * e2.eval() } Add(Atom(1),Mult(Atom(2),Atom(3))).eval() /* - calculeaza valoarea unei expresii - group: e1 * e2 + e1 * e3 = e1 * (e2 + e3) */ def group(e: Expr): Expr = e match{ case Add(Mult(e1,e2),Mult(e3,e4)) => if (e1 == e3) Mult(e1,Add(e2,e4)) else ??? } /* Liste in Scala */ val l1 = List(1,2,3,4) val l2 = 1 :: 2 :: 3 :: 4 :: Nil l1.head l2.tail def sum(l: List[Int]):Int = l match { case Nil => 0 case x::xs => x + sum(xs) } def prod(l: List[Int]):Int = l match { case Nil => 1 case x::xs => x * prod(xs) } // valoarea initiala // op def fold1(b: Int)(op: (Int,Int) => Int)(l: List[Int]): Int = l match { case Nil => b case x :: xs => op(x,fold1(b)(op)(xs)) } // (x: Int,y: Int) => x - y val sum1: List[Int] => Int = fold1(0)(_ + _) fold1(100)(_ - _)(List(1,2,3)) // 100 - 1 - 2 - 3 (?!) (Nope) // 1 - (2 - (3 - 100)) // x1 `op` (x2 `op` (x3 `op` b)) // ((b @ x1) @ x2) @ x3 def foldLeft(b: Int)(op:(Int, Int) => Int)(l: List[Int]): Int = { def loop (acc: Int, l: List[Int]): Int = l match { case Nil => acc case x :: xs => loop(op(acc,x), xs) } loop(b,l) } List(1,2,3).foldRight(0)(_ + _) List(1,2,3).foldLeft(0)(_ - _) /* def reverse(l: List[Int]): List[Int] = l.foldLeft(Nil: List[Int])((acc,x) => x :: acc) */ def reverse(l: List[Int]): List[Int] = { def loop(acc: List[Int], l: List[Int]): List[Int] = l match { case Nil => acc case x :: xs => loop(x :: acc, xs) } loop(Nil,l) } reverse(List(1,2,3,4)) /* reverse: ((b < x1) < x2) < x3 x @ y este "introdu pe y in lista x" */ /* Avem un sir, care contine numere si whitespace. "12 4 560 3" Vrem sa realizam un split dupa whitespace al acestui sir: "12", "4", "560", "3" */ type Sir = List[Char] def split(s: Sir): List[Sir] = { def op (c: Char, acc: List[Sir]): List[Sir] = acc match { case Nil => if (c == ' ') Nil else List(List(c)) case x :: xs => if (c == ' ') Nil :: acc else (c :: x) :: xs } s.foldRight(Nil: List[Sir])(op) } split("12 3 4 5".toList)