/*
Scala este orientat obiect - totul este un obiect
Stilul functional de a reprezenta date
Definitia TDA-ului:
Void : List
Cons : E x List -> List
*/
trait IList //trait este ca interface (din Java)
case object Void extends IList
case class Cons(x: Int, xs: IList) extends IList
/*
Diferentele intre "case class" si "class" in Scala:
1. un case class, are un SINGUR constructor
2. parametrii constructorului unui case class sunt IMUTABILI
3. un obiect construit cu un case class este IMUTABIL
4. egalitatea intre obiecte este STRUCTURALA
doua obiecte sunt egale daca sunt construite la fel
*/
// pattern matching - foarte des folosita in limbajele functionale
/*
Definition and axioms:
size: List -> Int
size(Void) = 1
size(Cons(x,xs)) = 1 + size(xs)
*/
def size(l: IList): Int =
l match {
case Void => 0
case Cons(_,xs) => 1 + size(xs)
}
/* Definition and axioms:
append: List x List -> List
append(Void,l) = l
append(Cons(x,xs),l)) = Cons(x,append(xs,l))
*/
def append(l1: IList, l2: IList): IList =
l1 match {
case Void => l2
case Cons(x,xs) => Cons(x,append(xs,l2))
}
append(Cons(1,Cons(2,Void)),Cons(3,Void))
/*
Definition and axioms:
reverse: List -> List
reverse(Void) = Void
reverse(Cons(x,xs)) = append(reverse(xs),Cons(x,Void))
*/
def reverse(l: IList): IList =
l match {
case Void => Void
case Cons(x,xs) => append(reverse(xs),Cons(x,Void))
}
reverse(Cons(1,Cons(2,Cons(3,Void))))
/*
Definition and axioms:
last: List -> Int
last (Cons(x,Void)) = x
last (Cons(x,Cons(y,ys))) = last(Cons(y,ys))
*/
def last(l: IList): Int =
l match {
case Cons(x,Void) => x
case Cons(_,Cons(y,ys)) => last(Cons(y,ys))
}