scala> 3+5;
res0: Int = 8
scala> res0 * 2;
res1: Int = 16
// val name are immutable:
scala> val six = 6;
six: Int = 6
scala> six = 7;
error: reassignment to val
six = 7;
^
// var names are mutable:
scala> var n = 1;
n: Int = 1
scala> n = 2;
n: Int = 2
// function definition:
scala> def succ(x: Int) = x + 1;
succ: (x: Int)Int
scala> succ(12);
res2: Int = 13
// lambda function:
scala> val succ = (x : Int) => x + 1;
succ: (Int) => Int = <function1>
scala> succ(3);
res3: Int = 4
// recursive function:
scala> def fact(n:Int): Int = if (n == 0) 1 else n * fact(n-1);
fact: (n: Int)Int
scala> true;
res4: Boolean = true
scala> false;
res5: Boolean = false
scala> 3;
res6: Int = 3
scala> 43.3;
res7: Double = 43.3
// most types fully compatible with Java:
scala> "moo";
res8: java.lang.String = moo
scala> val str = "cow";
str: java.lang.String = cow
scala> str.length();
res9: Int = 3
scala> str.toUpperCase();
res10: java.lang.String = COW
// Abbreviates in method calls with no arguments:
scala> str.toUpperCase;
res11: java.lang.String = COW
scala> str toUpperCase;
res12: java.lang.String = COW
scala> val tuple = (1,"moo");
tuple: (Int, java.lang.String) = (1,moo)
scala> val (x,y) = tuple;
x: Int = 1
y: java.lang.String = moo
scala> var n = 0;
n: Int = 0
scala> while (n < 3) { println(n); n = n + 1; }
0
1
2
scala> for (n <- 1 to 3) { println(n); }
1
2
3
More on For loops later...
scala> val list = List[Int](1,2,3);
list: List[Int] = List(1, 2, 3)
scala> val strList = List[String]("1","2","3");
strList: List[String] = List(1, 2, 3)
scala> val empty = Nil;
empty: scala.collection.immutable.Nil.type = List()
// cons and append operations
scala> 2 :: list
res15: List[Int] = List(2, 1, 2, 3)
scala> list ::: list
res16: List[Int] = List(1, 2, 3, 1, 2, 3)
// a polymorphic function (with matching)
scala> def build[T](t : T, n : Int) : List[T] =
n match {
case 0 => Nil
case v => t :: build(t, v-1);
}
build: [T](t: T,n: Int)List[T]
scala> build("cow",3);
res17: List[java.lang.String] = List(cow, cow, cow)
// Can iterate over lists with for loop (Iteratables)
scala> for (l <- list) println(l);
1
2
3
scala> val list = List("A","B","C");
list: List[java.lang.String] = List(A, B, C)
scala> list.head;
res19: java.lang.String = A
scala> list.length;
res20: Int = 3
scala> list(2);
res21: java.lang.String = C
scala> list.foreach(x => println(x));
A
B
C
scala> list.foreach(println(_));
A
B
C
scala> for (l <- 1 to 3) println(l);
1
2
3
scala> 1 to 3;
res26: scala.collection.immutable.Range.Inclusive ... = Range(1, 2, 3)
scala> (1 to 3).foreach(println(_));
1
2
3
scala> for (c <- "moo") println(c.toUpper);
M
O
O
// The usual map / filter / etc operations
scala> val list = List(11,21,31);
list: List[Int] = List(11, 21, 31)
scala> list.map( (x : Int) => "#" + x.toString);
res29: List[java.lang.String] = List(#11, #21, #31)
scala> list.filter(_<=21);
res30: List[Int] = List(11, 21)
// foldLeft is a CURRIED method
scala> list.foldLeft (0) ( (result,x) => result + x );
res31: Int = 63
scala> list.foldLeft (0) (_ + _)
res32: Int = 63
scala> list.foldLeft ("") ( (result,x) => result + " #" + x);
res33: java.lang.String = #11 #21 #31
scala> list.foldLeft ("") ( _ + " #" + _)
res34: java.lang.String = #11 #21 #31
// mutation via mutable name (but immutable lists...)
scala> var list2 = List(1,2,3);
list2: List[Int] = List(1, 2, 3)
scala> list2 = 2 :: list2;
list2: List[Int] = List(2, 1, 2, 3)
scala> list2 = list2 ::: list2;
list2: List[Int] = List(2, 1, 2, 3, 2, 1, 2, 3)
// mutable List structure
scala> import scala.collection.mutable.MutableList;
scala> val mlist = new MutableList[Int]();
mlist: scala.collection.mutable.MutableList[Int] = MutableList()
scala> mlist += 3;
res38: mlist.type = MutableList(3)
scala> mlist ++= mlist;
res39: mlist.type = MutableList(3, 3, 3)
scala> mlist ++= mlist;
res40: mlist.type = MutableList(3, 3, 3, 3, 3, 3, 3)
scala> mlist.foreach(println(_));
3
3
3
3
3
3
3
3
3
3
3
3
3
3
3
scala> (0 /: mlist) (_+_);
res43: Int = 45
scala> var romans = Map(1 -> "I", 2 -> "II", 3 -> "III", 4 -> "IV")
romans: scala.collection.immutable.Map[Int,java.lang.String] =
Map((1,I), (2,II), (3,III), (4,IV))
scala> romans(4);
res44: java.lang.String = IV
scala> romans(6);
java.util.NoSuchElementException: key not found: 6
at scala.collection.MapLike$class.default(MapLike.scala:223)
at scala.collection.immutable.HashMap.default(HashMap.scala:35)
...
scala> romans += (6 -> "VI");
scala> romans(6);
res47: java.lang.String = VI
//Mutable fields x and y, accessor methods, overriding a method
class Point {
var x = 0;
var y = 0;
def getX() = x;
def getY() = y;
override def toString() = {
"(" + x + "," + y + ")";
}
}
object PointMain {
def main(args : Array[String]) = {
val p = new Point();
println(p.toString());
p.x = 3;
println(p.toString());
}
}
// Constructor values, immutable x, mutable y
class Point(val x : Int, var y : Int) {
def getX() = x;
def getY() = y;
override def toString() = {
"(" + x + "," + y + ")";
}
}
object PointMain {
def main(args : Array[String]) = {
val p = new Point(1,0);
println(p.toString()); // prints (1,0)
p.y = 2;
println(p.toString()); // prints (1,2)
}
}
// And ColorPoints...
class ColorPoint(val color : String, x : Int, y : Int)
extends Point(x,y) {
override def toString() = {
super.toString() + " -- " + color;
}
}
object PointMain {
def main(args : Array[String]) = {
val p = new ColorPoint("red",0,0);
p.y = 2;
println(p.toString());
}
}
class MultiSet[T] {
var elems = List[T]();
def add(t : T) : Unit = {
elems = t::elems;
}
def addAll(ts : List[T]) : Unit = {
elems = elems:::ts;
}
def count(t : T) : Int = {
elems.count(_ == t);
}
}
object MultiSet {
def main(args : Array[String]) = {
val s = new MultiSet[String]();
s.add("cow");
s.add("Moo");
s.add("cow");
s.add("cow");
s.add("cow");
println(s.count("cow"));
val s2 = new MultiSet[Int]();
s2.addAll(List(1,2,3,2,1,2,3,3));
println(s2.count(3));
}
}
class Rational(x: Int, y: Int = 1) {
private def gcd(a: Int, b: Int): Int = {
if (b == 0) a else gcd(b, a % b);
}
private val g = gcd(x, y);
val numer = x / g;
val denom = y / g;
def +(that: Rational) =
new Rational(numer * that.denom + that.numer * denom,
denom * that.denom);
def -(that: Rational) =
new Rational(numer * that.denom - that.numer * denom,
denom * that.denom);
def *(that: Rational) =
new Rational(numer * that.numer, denom * that.denom);
def /(that: Rational) =
new Rational(numer * that.denom, denom * that.numer);
override def toString = numer + "/" + denom;
}
object Rational {
def main(args : Array[String]) = {
val a = new Rational(2, 4)
val b = new Rational(3)
println(a + " + " + b + " = " + (a + b))
println(a + " - " + b + " = " + (a - b))
println(a + " * " + b + " = " + (a * b))
println(a + " / " + b + " = " + (a / b))
}
}
/*
An example of case classes for Expresssion Trees. We use pattern
matching to convert a tree to a String, and standard method
inheritance and virtual dispatch to "flip" an expression by negating
numbers and changing oeprators.
*/
// sealed means no subclasses outside of this file.
sealed abstract class Expr {
def flip() : Expr // abstract method
}
case class Constant(x: Double) extends Expr {
override def flip() = Constant(-x)
}
case class Sum(l: Expr, r: Expr) extends Expr {
override def flip() = Product(l.flip(), r.flip())
}
case class Product(l: Expr, r: Expr) extends Expr {
override def flip() = Sum(l.flip(), r.flip())
}
object Expr {
def makeString(exp: Expr): String = {
exp match {
case Constant(x) => x.toString
case Sum(l, r)
=> "(" + makeString(l) + " + " + makeString(r) + ")"
case Product(l, r)
=> "(" + makeString(l) + " * " + makeString(r) + ")"
}
}
def main(args : Array[String]) {
val e = Product(Sum(Constant(1), Constant(4)), Constant(6))
println(makeString(e.flip()))
}
}
class Color(val red:Int, val green:Int, val blue:Int) {
def negate() = new Color(255 - red, 255 - green, 255 - blue);
}
case class Red(r:Int) extends Color(r, 0, 0);
case class Green(g:Int) extends Color(0, g, 0);
case class Blue(b:Int) extends Color(0, 0, b);
object Color {
def printColor(c:Color) = {
c match {
case Red(v) => println("Red: " + v)
case Green(v) => println("Green: " + v)
case Blue(v) => println("Blue: " + v)
case col:Color => {
print("(" + col.red + ",")
print(col.green + ",")
println(col.blue + ")")
}
}
}
def main(args : Array[String]) {
printColor(Red(100));
printColor(Blue(220));
printColor(Blue(220).negate);
printColor(new Color(100, 200, 50));
}
}
scala> val result = romanNumeral.get(11);
result: Option[java.lang.String] = None
// See Def of Map
scala> result match {
case None => println("Not Found");
case Some(v) => println(v);
}
Not Found
// Option implementation
sealed abstract class Option[+A] ... {
def isEmpty: Boolean
def get: A
}
case class Some[+A](x: A) extends Option[A] {
def isEmpty = false
def get = x
}
case object None extends Option[Nothing] {
def isEmpty = true
def get = throw new NoSuchElementException("None.get")
}
Map
Map's apply method gets called when romanNumberal(3) is evaluation