From 1a7d6ef072ba2ee7aad39712cf2c48ef8657880d Mon Sep 17 00:00:00 2001
From: Matt Bovel <matthieu.bovel@epfl.ch>
Date: Mon, 13 Dec 2021 03:00:02 +0100
Subject: [PATCH] Add exercises/solution-09.md

---
 exercises/solution-09.md | 44 +++++++++++++++++++++++++++-------------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/exercises/solution-09.md b/exercises/solution-09.md
index 76704aa..44333d6 100644
--- a/exercises/solution-09.md
+++ b/exercises/solution-09.md
@@ -2,18 +2,18 @@
 
 ## Question 1
 
-```scala
+```scala mdoc
 def groupBy[T, S](f: T => S)(xs: List[T]): Map[S, List[T]] =
-    var acc = Map[S, List[T]]()
+    var result = Map[S, List[T]]()
     xs.reverse.foreach(el =>
         val key = f(el)
-        val prevValue = acc.getOrElse(key, List())
-        acc = acc.updated(key, el :: prevValue)
+        val prevValue = result.getOrElse(key, List())
+        result = result.updated(key, el :: prevValue)
     )
-    acc
+    result
 ```
 
-```scala
+```scala mdoc
 def groupBy2[T, S](f: T => S)(xs: List[T]): Map[S, List[T]] =
     xs.foldRight(Map[S, List[T]]())((el: T, acc: Map[S, List[T]]) =>
         val key = f(el)
@@ -24,21 +24,20 @@ def groupBy2[T, S](f: T => S)(xs: List[T]): Map[S, List[T]] =
 
 Example run:
 
-```scala
+```scala mdoc
 groupBy[Int, Int](_ % 3)((0 to 10).toList)
-// res0: Map[Int, List[Int]] = Map(
-//   1 -> List(1, 4, 7, 10),
-//   0 -> List(0, 3, 6, 9),
-//   2 -> List(2, 5, 8)
-// )
 ```
 
 ## Question 2
 
 ### Question 2.1
 
+```scala mdoc:invisible
+trait Logger:
+    def log(message: String): Unit
+```
 
-```scala
+```scala mdoc
 class LoggerBuffered extends Logger:
     private var output: String = ""
     def log(message: String): Unit = output = output + message + "\n"
@@ -47,8 +46,25 @@ class LoggerBuffered extends Logger:
 
 ### Question 2.2
 
+```scala mdoc:invisible
+enum Expr:
+  case Var(name: String)
+  case Op(name: String, args: List[Expr])
+
+import Expr._
+
+final case class UnknownVarException(name: String) extends Exception
+final case class UnknownOpException(name: String) extends Exception
+
+def eval(e: Expr, context: Map[Var, Int]): Int = e match 
+    case sym: Var if context.contains(sym) => context(sym)
+    case sym: Var => throw UnknownVarException(sym.name)
+    case Op("*", args) => args.map(eval(_, context)).foldLeft(1)(_ * _)
+    case Op("+", args) => args.map(eval(_, context)).foldLeft(0)(_ + _)
+    case Op(name, _) => throw UnknownOpException(name)
+```
 
-```scala
+```scala mdoc
 def evalTracing(e: Expr, context: Map[Var, Int])(using logger: Logger): Int = e match 
     case sym: Var if context.contains(sym) =>
         val value = context(sym)
-- 
GitLab