Skip to content

Commit

Permalink
Document exercises
Browse files Browse the repository at this point in the history
  • Loading branch information
Abhijit Sarkar committed Dec 22, 2024
1 parent 3d7f461 commit 7d88efe
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 0 deletions.
8 changes: 8 additions & 0 deletions ch02/src/MyList.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ enum MyList[A]:
case Empty()
case Pair(_head: A, _tail: MyList[A])

/*
Exercise: Map
Once you’ve completed iterate, try to implement map in terms of unfold.
*/
def map[B](f: A => B): MyList[B] =
// this match
// case Empty() => Empty()
Expand Down Expand Up @@ -50,5 +54,9 @@ object MyList:
def fill[A](n: Int)(elem: => A): MyList[A] =
unfold(0)(_ == n, _ => elem, _ + 1)

/*
Exercise: Iterate
Implement iterate using the same reasoning as we did for fill.
*/
def iterate[A](start: A, len: Int)(f: A => A): MyList[A] =
unfold((0, start))(_._1 == len, _._2, (i, a) => (i + 1, f(a)))
19 changes: 19 additions & 0 deletions ch02/src/Tree.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ enum Tree[A]:
case Leaf(value: A)
case Node(left: Tree[A], right: Tree[A])

/*
Exercise: Methods for Tree
Write some methods for Tree. Implement
- size, which returns the number of values (Leafs) stored in the Tree;
- contains, which returns true if the Tree contains a given element of type A, and false otherwise; and
- map, which creates a Tree[B] given a function A => B
Use whichever you prefer of pattern matching or dynamic dispatch to implement the methods.
Exercise: Using Fold
Prove to yourself that you can replace structural recursion with calls to fold,
by redefining size, contains, and map for Tree using only fold.
*/
/** @return
* the number of values (Leafs) stored in the Tree
*/
Expand Down Expand Up @@ -38,6 +53,10 @@ enum Tree[A]:
// case Tree.Leaf(value) => Tree.Leaf(f(value))
// case Tree.Node(left, right) => Tree.Node(left.map(f), right.map(f))

/*
Exercise: Tree Fold
Implement a fold for Tree defined earlier.
*/
def fold[B](f: (A => B), g: (B, B) => B): B =
this match
case Tree.Node(left, right) => g(left.fold(f, g), right.fold(f, g))
Expand Down
4 changes: 4 additions & 0 deletions ch03/src/Bool.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ def and(l: Bool, r: Bool): Bool =
def `if`[A](t: A)(f: A): A =
l.`if`(r)(False).`if`(t)(f)

/*
Exercise: Or and Not
Test your understanding of Bool by implementing or and not.
*/
def or(l: Bool, r: Bool): Bool =
new Bool:
def `if`[A](t: A)(f: A): A =
Expand Down
3 changes: 3 additions & 0 deletions ch03/src/Set.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package ch03

/*
3.6 Exercise: Sets
*/
trait Set[A]:

def contains(elt: A): Boolean
Expand Down
4 changes: 4 additions & 0 deletions ch03/src/Stream.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ trait Stream[A]:
def head: B = f(self.head)
def tail: Stream[B] = self.tail.map(f)

/*
Exercise: Stream Combinators
Implement filter, zip, and scanLeft on Stream.
*/
def filter(p: A => Boolean): Stream[A] =
lazy val self = if p(head) then this else tail.filter(p)
new Stream[A]:
Expand Down
3 changes: 3 additions & 0 deletions ch04/src/Display.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package ch04

/*
4.5 Exercise: Display Library
*/
trait Display[A]:
def display(value: A): String

Expand Down
13 changes: 13 additions & 0 deletions ch05/src/Expression.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ has every method call in tail position. Due to Scala runtime limitations not all
in tail position can be converted to tail calls, so we reified calls and returns into
data structures used by a recursive loop called a trampoline.
*/
/*
Exercise: Arithmetic
Now it’s your turn to practice using reification. Your task is to implement an interpreter
for arithmetic expressions. An expression is:
- a literal number, which takes a Double and produces an Expression;
- an addition of two expressions;
- a substraction of two expressions;
- a multiplication of two expressions; or
- a division of two expressions;
Reify this description as a type Expression.
*/
enum Expression:
case Literal(value: Double)
case Addition(left: Expression, right: Expression)
Expand Down
1 change: 1 addition & 0 deletions ch05/src/ExpressionC.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ch05

// Continuation-Passing style.
/* Exercise: CPS Arithmetic */
enum ExpressionC:
case Literal(value: Double)
case Addition(left: ExpressionC, right: ExpressionC)
Expand Down
1 change: 1 addition & 0 deletions ch05/src/ExpressionT.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ch05

/* Exercise: Trampolined Arithmetic */
enum ExpressionT:
case Literal(value: Double)
case Addition(left: ExpressionT, right: ExpressionT)
Expand Down

0 comments on commit 7d88efe

Please sign in to comment.