Programmation appliquée en Scala

Copyright © Cay S. Horstmann 2015 Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License

A Better switch

Variables and Guards

Type Patterns

What Value Can x Never Be?

x match {
  case Foo => 1
  case y: Foo => 2
  case foo => 3
  case _ => 4
}
  1. 1
  2. 2
  3. 3
  4. 4

Case Classes

Example: Option

Extracting Matches

Extractors

How Many Are Valid?

val t1 = Tuple2(3, 4)
val t2 = new Tuple2(3, 4)
val t3 = Tuple2.apply(3, 4)
val t4 = new Tuple2.apply(3, 4)
val Tuple2(x, y) = t1
val Tuple2(a, b) = Tuple2.unapply(t1)
val t5 = Tuple2.unapply(t1)
  1. 4
  2. 5
  3. 6
  4. Something else

Infix Extractors

Lab

Scary looking lab

Part 1: The Option Type

  1. In this part, you will reimplement the Option type for Double values. Provide Option, Some, and None. What are they?
  2. Write a function inv that maps x into its inverse (1 / x), returning an Option. Return None when x is zero. What is your function? What happens when you call inv(2)? inv(0)?
  3. Define a method isEmpty that returns true for None and false for Some.
  4. Now define a method get that returns the value wrapped in Some and throws a NoSuchElementException if there is no value. There are two ways of defining methods on an Option. You can either define a method in Option, using pattern matching. Or you can leave the method abstract in Option and override it in Some and None. In this step, use whichever approach you didn't use in the preceding step.
  5. Define a method getOrElse that returns the value wrapped in Some and a default if there is no value. Do this by calling isEmpty/get

Part 2: Lists

  1. In this part, you will implement a List type for Double values. A list is either Nil or a node with a head that's a Double and a tail that's again a List. Such a node is traditionally called a Cons node. Define the types List, Nil, and Cons.
  2. Now write a function (outside any of these classes) that computes the sum of all elements in a list, using recursion and pattern matching. Test it with Cons(3, Cons(4, Cons(5, Nil))).
  3. That's an ugly way of making lists. Instead, define a method of List called :: that lets you make a list as 3.0 :: 4.0 :: 5.0 :: Nil. What special rule for operators (briefly mentioned in Unit 7) makes this work?
  4. Have a close look how 3.0 :: 4.0 :: 5.0 :: Nil is printed in the worksheet. Fix it by defining toString so that it shows up as 3.0 :: 4.0 :: 5.0 :: Nil.
  5. Right now, to use pattern matching in lists, you write
    case Cons(h, t) => ...
    It would be prettier to write
    case h :: t => ...
    That's achieved by renaming the class Cons into ::. Do that, and fix up the sum function to match. Don't change the name of the :: method. There is both a :: method (used for construction) and a :: class (for extraction). You may run into a problem in your definition of the :: method. If you do, fix it by adding new.
  6. Why didn't you have to define an unapply method in the preceding step?

Part 3: Expressions

  1. An expression is either a number or an operation. Make case classes Num and Op so that one can make expressions such as
    Op("+", Op("*", Num(2), Num(3)), Num(4))
    Hint: You need a common superclass, like this:
    abstract class Expr
    case class Op(...) extends Expr
  2. Write a function eval that evaluates an expression such as the one given above. Use pattern matching and recursion:
    def eval(e: Expr): Int = e match { ... }
    

Homework

Do this as individual work, not with your partner

When all done, email the signed zip files to Fatemeh.Borran@heig-vd.ch