Instructor: James Riely
def printList (xs:List[Int]) : Unit = 
val xs = List(11,21,31)
printList (xs)
          
            
  
          
        
def printList (xs:List[Int]) : Unit = xs match 
  case Nil   => ()
  case x::xt => 
    printList (xt)
val xs = List(11,21,31)
printList (xs)
          
          
  
          
        
def printList (xs:List[Int]) : Unit = xs match 
  case Nil   => ()
  case x::xt => 
    println (x)
    printList (xt)
val xs = List(11,21,31)
printList (xs)
          
          
11
21
31
          
        
def printListFormat (xs:List[Int]) : Unit = xs match 
  case Nil   => ()
  case x::xt => 
    println ("0x%02x".format(x))
    printListFormat (xt)
val xs = List(11,21,31)
printListFormat (xs)
          
          
0x0b
0x15
0x1f
          
        
def printListLengths (xs:List[List[Int]]) : Unit = xs match 
  case Nil   => ()
  case x::xt => 
    println (x.length)
    printListLengths (xt)
val xss = List(List(11,21,31),List(),List(41,51))
printListLengths (xss)
          
          
3
0
2
          
        
def foreach (xs:List[Int], f:Int=>Unit) : Unit = xs match 
  case Nil   => ()
  case x::xt => 
    f (x)
    foreach (xt, f)
val xs = List(11,21,31)
foreach (xs, println)
            
            
11
21
31
            
          
def foreach (xs:List[Int], f:Int=>Unit) : Unit = xs match 
  case Nil   => ()
  case x::xt => 
    f (x)
    foreach (xt, f)
def printHex (x:Int) = println("0x%02x".format(x))
val xs = List(11,21,31)
foreach (xs, printHex)
            
            
0x0b
0x15
0x1f
            
          
def foreach [X] (xs:List[X], f:X=>Unit) : Unit = xs match 
  case Nil   => ()
  case x::xt =>  
    f (x)
    foreach (xt, f)
def printLength (xs:List[Int]) = println (xs.length)
val xss = List(List(11,21,31),List(),List(41,51))
foreach (xss, printLength)
          
          
3
0
2
          
        
def foreach [X] (xs:List[X], f:X=>Unit) : Unit = xs match 
  case Nil   => ()
  case x::xt => 
    f (x)
    foreach (xt, f)
val xss = List(List(11,21,31),List(),List(41,51))
foreach (xss, (xs:List[Int]) => println (xs.length))
          
          
3
0
2
          
        
foreach (xss, (xs:List[Int]) => println (xs.length))
          
          
def printLength (xs:List[Int]) = println (xs.length)
foreach (xss, printLength)
          
          
val printLength = (xs:List[Int]) => println (xs.length)
foreach (xss, printLength)
                        
          f is a function parameter
	  
def foreach [X] (xs:List[X], f:X=>Unit) : Unit = ...
          
          
foreach: [X](xs: List[X], f: X => Unit)Unit
          
	  f has type X=>Unit
	  X
	    Unit
	    foreachList class has foreach method
          
xs.foreach ((x:Int) => println ("0x%02x".format(x)))
          
          
0x0b
0x15
0x1f
          
          foreach function
            
foreach (xs, ((x:Int) => println ("0x%02x".format(x)))
            
            
0x0b
0x15
0x1f
            
          
xs.foreach (x => println ("0x%02x".format(x)))
          
          
0x0b
0x15
0x1f
          
        foreach
for x <- xs do println ("0x%02x".format(x))
          
          
xs.foreach (x => println ("0x%02x".format(x)))
            
          foreach and more...
            
val add = (x:Int, y:Int) => x+y
add(11,21)
          
          
val add = (_:Int) + (_:Int)
add(11,21)
            
          
var add : (Int,Int)=>Int = null  
add = (x,y) => x+y
add = _ + _
add(11,21)
            
        
        foreach and a variable in scope
          
def sum (xs:List[Int]) : Int = 
  var result = 0
  xs.foreach ((x:Int) => result = result + x)
  result
          
          
def foreach [X] (xs:List[X], f:X=>Unit) : Unit = 
  println("call foreach(%s)".format(xs))
  xs match 
    case Nil   => ()
    case x::xt => 
      f (x)
      foreach (xt, f)
  println("rtrn foreach(%s)".format(xs))
val xs = List(21,31)
foreach (xs, (x:Int) => ())
          
          
call foreach(List(21, 31))
call foreach(List(31))
call foreach(List())
rtrn foreach(List())
rtrn foreach(List(31))
rtrn foreach(List(21, 31))
          
        
def reference (xs:List[Int]) : List[Int] = xs
xs eq reference(xs) /* reference equality */
xs == reference(xs) /* value equality */
          
          res1: Boolean = true
res2: Boolean = true
          
        
def copy (xs:List[Int]) : List[Int] = xs match 
  case Nil   => Nil
  case x::xt => x::copy(xt)
xs eq copy(xs) /* reference equality */
xs == copy(xs) /* value equality */
          
          res1: Boolean = false
res2: Boolean = true
          
        
def transform (xs:List[Int]) : List[String] = xs match 
  case Nil   => Nil
  case x::xt => ("0x%02x".format (x)) :: transform (xt)
val xs = List(11,21,31)
transform(xs)
          
          res1: List[String] = List(0x0b, 0x15, 0x1f)
          
        
def transform (xs:List[List[Int]]) : List[Int] = xs match 
  case Nil   => Nil
  case x::xt => (x.length) :: transform (xt)
val xss = List(List(11,21,31),List(),List(41,51))
transform(xss)
          
          res1: List[Int] = List(3, 0, 2)
          
        
def transform (xs:List[Int]) : List[String] = xs match 
  case Nil   => Nil
  case x::xt => ("0x%02x".format (x)) :: transform (xt)
val xs = List(11,21,31)
transform(xs)
          
          
transform (11::(21::(31::Nil)))
--> 0x0b::(transform (21::(31::Nil)))
--> 0x0b::(0x15::(transform (31::Nil)))
--> 0x0b::(0x15::(0x1f::(transform (Nil))))
--> 0x0b::(0x15::(0x1f::(Nil)))
          
        
def map (xs:List[Int], f:Int=>String) : List[String] = xs match 
  case Nil   => Nil
  case x::xt => f(x) :: map (xt, f)
val xs = List(11,21,31)
map(xs, "0x%02x".format (_))
          
          
map (11::(21::(31::Nil)), f)
--> 0x0b::(map (21::(31::Nil), f))
--> 0x0b::(0x15::(map (31::Nil, f)))
--> 0x0b::(0x15::(0x1f::(map (Nil, f))))
--> 0x0b::(0x15::(0x1f::(Nil)))
          
        
def map (xs:List[Int], f:Int=>String) : List[String] = xs match 
  case Nil   => Nil
  case x::xt => f(x) :: map (xt, f)
val xs = List(11,21,31)
map(xs, "0x%02x".format (_))
          
          
map (11::(21::(31::Nil)), f)
--> f(11)::(map (21::(31::Nil), f))
--> f(11)::(f(21)::(map (31::Nil, f)))
--> f(11)::(f(21)::(f(31)::(map (Nil, f))))
--> f(11)::(f(21)::(f(31)::(Nil)))
          
        
def map [X,Y] (xs:List[X], f:X=>Y) : List[Y] = xs match 
  case Nil   => Nil
  case x::xt => f(x) :: map (xt, f)
val xs = List(11,21,31)
map(xs, (x:Int) => "0x%02x".format (x))
          
          
map (11::(21::(31::Nil)), f)
--> f(11)::(map (21::(31::Nil), f))
--> f(11)::(f(21)::(map (31::Nil, f)))
--> f(11)::(f(21)::(f(31)::(map (Nil, f))))
--> f(11)::(f(21)::(f(31)::(Nil)))
          
        
def copy [X] (xs:List[X]) : List[X] = xs match 
  case Nil   => Nil
  case x::xt => x :: copy (xt)
val xs = List(11,21,31)
copy(xs)
          
          
copy (11::(21::(31::Nil)))
--> 11::(copy (21::(31::Nil)))
--> 11::(21::(copy (31::Nil)))
--> 11::(21::(31::(copy (Nil))))
--> 11::(21::(31::(Nil)))
          
        copy(xs) same as map (xs, x=>x) 
          
def map [X,Y] (xs:List[X], f:X=>Y) : List[Y] = xs match 
  case Nil   => Nil
  case x::xt => f(x) :: map (xt, f)
val xs = List(11,21,31)
map(xs, (x:Int) => "0x%02x".format (x))
          
          
map (11::(21::(31::Nil)), f)
--> f(11)::(map (21::(31::Nil), f))
--> f(11)::(f(21)::(map (31::Nil, f)))
--> f(11)::(f(21)::(f(31)::(map (Nil, f))))
--> f(11)::(f(21)::(f(31)::(Nil)))
          
        
def foe [X]   (xs:List[X], f:X=>Unit) : Unit = xs match 
  case Nil   => ()
  case x::xt =>{f(x) ;  foe (xt, f) }
val xs = List(11,21,31)
foe(xs, (x:Int) => println ("0x%02x".format(x)))
          
          
foe (11::(21::(31::Nil)))
--> foe (21::(31::Nil))
--> foe (31::Nil)
--> foe (Nil)
--> ()
          
        map
xs.map ("0x%02x".format (_))
          
          
res1: List[String] = List(0x0b, 0x15, 0x1f)
          
          
map (xs, "0x%02x".format (_))
            
            
res1: List[String] = List(0x0b, 0x15, 0x1f)
                        
          map
for x <- xs yield "0x%02x".format(x)
          
          
for x <- xs do println ("0x%02x".format(x))
          
          
xs.map (x => "0x%02x".format(x))
            
            
xs.foreach (x => println ("0x%02x".format(x)))
            
          
val xss = List(List(11,21,31),List(),List(41,51))
xss.map (_.length)
            
            
res1: List[Int] = List(3, 0, 2)
            
          
val ys = List("hi", "mom", "it's", "me")
ys.map (_.length)
            
            
res1: List[Int] = List(2, 3, 4, 2)
            
          
def copy    [X] (xs:List[List[X]]) : List[List[X]] = xs match 
  case Nil   => Nil
  case x::xt => x ::  copy    (xt)
val xss = List(List(11,21,31),List(),List(41,51))
          
          
    copy   (List(11,21,31) ::  List() ::  List(41,51) ::  Nil)
--> List(11,21,31) ::  copy   (List() ::  List(41,51) ::  Nil)
--> List(11,21,31) ::  List() ::  copy   (List(41,51) ::  Nil)
--> List(11,21,31) ::  List() ::  List(41,51) ::  copy   (Nil)
--> List(11,21,31) ::  List() ::  List(41,51) ::  Nil
=== List(List(11,21,31), List(), List(41,51))
          
        :: with :::
          
def flatten [X] (xs:List[List[X]]) : List[X] = xs match 
  case Nil   => Nil
  case x::xt => x ::: flatten (xt)
val xss = List(List(11,21,31),List(),List(41,51))
          
          
    flatten(List(11,21,31) ::  List() ::  List(41,51) ::  Nil)
--> List(11,21,31) ::: flatten(List() ::  List(41,51) ::  Nil)
--> List(11,21,31) ::: List() ::: flatten(List(41,51) ::  Nil)
--> List(11,21,31) ::: List() ::: List(41,51) ::: flatten(Nil)
--> List(11,21,31) ::: List() ::: List(41,51) ::: Nil
=== List(11,21,31,41,51)
          
        
def map     [X,Y] (xs:List[X], f:X=>List[Y]) : List[List[Y]] = xs match 
  case Nil   => Nil
  case x::xt => f(x) ::  map     (xt, f)
val as = List(3,0,2)
map    (as, (x:Int) => (11 to x*10+1 by 10).toList)
          
          
          
map     (3::0::2::Nil, f)
--> List(11,21,31):: map     (0::2::Nil, f)
--> List(11,21,31):: List():: map     (2::Nil, f)
--> List(11,21,31):: List():: List(11,21):: map     (Nil, f)
--> List(11,21,31):: List():: List(11,21):: Nil
=== List(List(11,21,31), List(), List(11,21))
          
        :: with :::            
          
def flatMap [X,Y] (xs:List[X], f:X=>List[Y]) : List[Y] = xs match 
  case Nil   => Nil
  case x::xt => f(x) ::: flatMap (xt, f)
val as = List(3,0,2)
flatMap(as, (x:Int) => (11 to x*10+1 by 10).toList)
          
          
          
flatMap (3::0::2::Nil, f)
--> List(11,21,31):::flatMap (0::2::Nil, f)
--> List(11,21,31):::List():::flatMap (2::Nil, f)
--> List(11,21,31):::List():::List(11,21):::flatMap (Nil, f)
--> List(11,21,31):::List():::List(11,21):::Nil
=== List(11,21,31,11,21)
          
        f:X=>List[Y]
              List[Y]
                xs
                f:X=>List[Y]
              Y
                List[Y]
                flatMap
for xs <- xss; x <- xs yield x + 1
          
          
xss.flatMap( xs => xs.map (x => x + 1) )
          
          
xss.map( xs => xs.map (x => x + 1) ).flatten
          
        
val xss = List(List(11,21,31),List(),List(41,51))
for
  xs <- xss
  x <- xs
yield
  (x, xs.length)
          
          
res1: List[(Int, Int)] = List((11,3), (21,3), (31,3), (41,2), (51,2))
          
          
xss.flatMap (xs => xs.map (x => (x, xs.length)))
          
          
val xss = List(List(11,21,31),List(),List(41,51))
for
  xs <- xss
yield 
  for
    x <- xs
  yield
    (x, xs.length)
          
          
res1: List[List[(Int, Int)]] = List(List((11,3), (21,3), (31,3)), List(), List((41,2), (51,2)))
          
          
xss.map (xs => xs.map (x => (x, xs.length)))
          
          
val xs = List(100,200,300)
val ys = List(50,70)
val zs = List(3,6,9)
for
  x <- xs
  y <- ys
  z <- zs
yield
  x + y + z
            
            
res1: List[Int] = List(153, 156, 159, 173, 176, 179, 253, 256, 259, 273, 276, 279, 353, 356, 359, 373, 376, 379)
            
	    
xs.flatMap (x => ys.flatMap (y => zs.map (z => x + y z)))
            
        
(for x <- (10 to 70 by 10); y <- (1 to 9) yield x+y).length
            
            
res1: Int = 63
            
	    
(10 to 70 by 10).flatMap (x => (1 to 9).map (y => x+y)).length
            
        
val xs = List(11,21,31)
val ys = List("a","b")
for x <- xs; y <- ys yield (x, y)
          
          
xs : List[Int]
ys : List[String]
res1: List[(Int, String)] = List((11,a), (11,b), (21,a), (21,b), (31,a), (31,b))
          
          
x : Int
y : String
            
          
(x, y) : (Int, String)
for ... yield (x, y) : List[(Int, String)]
            
          
def copy   [X] (xs:List[X])               : List[X] = xs match 
  case Nil            => Nil
  case x::xt          => x :: copy   (xt)
val zs = (0 to 7).toList
copy(zs)
          
          
zs: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7)
res1: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7)
          
        f
          
def filter [X] (xs:List[X], f:X=>Boolean) : List[X] = xs match 
  case Nil            => Nil
  case x::xt if f (x) => x :: filter (xt, f)
  case _::xt          =>      filter (xt, f)
val zs = (0 to 7).toList
filter(zs, (_ % 3 != 0))
          
          
zs: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7)
res1: List[Int] = List(1, 2, 4, 5, 7)
          
        filter
for z <- zs; if z % 3 != 0 yield z
zs.filter (z => z % 3 != 0)
          
          
for z <- zs; if z % 3 != 0 yield "0x%02x".format(z)
zs.filter (z => z % 3 != 0).map (z => "0x%02x".format(z))
          
          
for z <- zs; if z % 3 != 0 do println ("0x%02x".format(z))
zs.filter (z => z % 3 != 0).foreach (z => println ("0x%02x".format(z)))