# <span class="fa-stack"><i class="fa-solid fa-circle fa-stack-2x"></i><i class="fa-solid fa-dumbbell fa-stack-1x fa-inverse"></i></span> Pattern Matching Example: Lists - :fa fa-terminal: ```text In Scala, implement a method that takes a list of at least 3 numbers and returns it with the first 3 numbers sorted in ascending order ``` * :fa fa-comment-dots: <div class="text-base"> ```scala def f (numbers: List[Int]) : List[Int] = { require(numbers.length >= 3, "The list must contain at least 3 elements") val (firstThree, rest) = numbers.splitAt(3) firstThree.sorted ++ rest } ensuring { (result: List[Int]) => ??? } ``` </div> - Contract for checking the first 3 elements <div class="grid grid-cols-3 gap-4"> <div data-marpit-fragment> **Index access** ```scala ensuring { (result: List[Int]) => val x1 = result(0) val x2 = result(1) val x3 = result(2) x1 <= x2 && x2 <= x3 } ``` </div> <div data-marpit-fragment> **Projections** ```scala ensuring { (result: List[Int]) => val x1 = result.head val x2 = result.tail.head val x3 = result.tail.tail.head x1 <= x2 && x2 <= x3 } ``` </div> <div data-marpit-fragment> **Pattern matching** ```scala ensuring { (result: List[Int]) => val x1 :: x2 :: x3 :: _ = result x1 <= x2 && x2 <= x3 } ``` ```scala ensuring { case x1 :: x2 :: x3 :: _ => x1 <= x2 && x2 <= x3 } ``` </div> </div> ---
* With types (optional) ```scala def sum (p: LinkedList) : Int = p match case Cons(x: Int, Cons(y: Int, tail: LinkedList)) => x+y case _ => throw IllegalArgumentException("...") ```
# <span class="fa-stack"><i class="fa-solid fa-circle fa-stack-2x"></i><i class="fa-solid fa-cubes fa-stack-1x fa-inverse"></i></span> Pattern Matching - Pattern matching vs. Projections <div class="grid grid-cols-2 gap-4"> <div> - Decomposition with pattern matching ```scala def f (xs: List[(Int,String)]) = xs match case Nil => "List is empty" case x :: Nil => s"List has one element: $x" case _ :: (x,_) :: _ => s"The second int is $x" end f val zs = List ((11,"dog"), (21,"cat"), (31,"sloth")) f(zs) // 21 ``` </div> <div> * Decomposition with projections ```scala def f (xs: List[(Int,String)]) = if xs == Nil then "List is empty" else if xs.tail == Nil then s"List has one element: ${xs.head}" else s"The second int is ${xs.tail.head(0)}" end f val zs = List ((11,"dog"), (21,"cat"), (31,"sloth")) f(zs) // 21 ``` </div> </div> ---
# <span class="fa-stack"><i class="fa-solid fa-circle fa-stack-2x"></i><i class="fa-solid fa-dumbbell fa-stack-1x fa-inverse"></i></span> Exercise: Linked List ADT - Open project `hw1` in VSCode, create a file `week2-patterns.sc` in folder `play` <div class="grid grid-cols-2 gap-4"> <div class="groupblock"> **Github Copilot** - Deactivate automatic suggestions - Add keyboard shortcut: `Cmd-Shift-P` - trigger inline suggestions - Chat commands <div class="text-sm"> - `/assess-exercise` - `/explain-code` - `/explain-compile-error` - `/find-resources` - `/infer-types` - `/make-exercise-plan` - `/step-exec` </div> </div> <div class="groupblock"> **Scala REPL** - Open a terminal - Open the Scala REPL: `sbt console` - Load and execute files `:load play/week2-patterns.sc` </div> </div> ---
# <span class="fa-stack"><i class="fa-solid fa-circle fa-stack-2x"></i><i class="fa-solid fa-dumbbell fa-stack-1x fa-inverse"></i></span> Exercise: Linked List ADT :fa fa-question-circle: Which "states" does a list have :fa fa-arrow-right: which case classes and case objects? - An `Empty` list and a `Cons` cell of at least one element ```scala enum LinkedList: case Empty case Cons (head: Int, tail: LinkedList) end LinkedList ``` ---