Implement BST using Scala Pattern Matching - scala

I am new to scala and was trying to implement a BST using Pattern Matching Concept in scala.
Edit: I have modified the insert function and now it is behaving in the expected manner, can someone help me to make it tail recursive?
Also, any other code improvements would be appreciated.
trait IntTree {
def contains(v: Int): Boolean
def insert(x: Int): IntTree
}
case object EmptyTree extends IntTree {
override def insert(x: Int): IntTree = Node(x, EmptyTree, EmptyTree)
override def contains(v: Int): Boolean = false
}
case class Node(elem: Int, left: IntTree, right: IntTree) extends IntTree {
override def contains(v: Int): Boolean = {
#scala.annotation.tailrec
def contains(t: IntTree, v: Int): Boolean = t match {
case Node(data, _, _) if (data == v) => true
case Node(data, l, r) => if (data > v) contains(l, v) else contains(r, v)
case _ => false
}
contains(this, v)
}
override def insert(x: Int): IntTree = {
def insert(t: IntTree, x: Int): IntTree = t match {
case Node(data, l, r) if (data > x) => Node(data, insert(l, x), r)
case Node(data, l, r) if (data < x) => Node(data, l, insert(r, x))
case EmptyTree => t insert x
case _ => t
}
insert(this, x)
}
}

It would require a revisit and update of the parent nodes after you go down the leaf:
sealed trait IntTree {
def contains(v: Int): Boolean
def insert(x: Int): Node // better to return Node here
}
def insert(x: Int): Node = {
#annotation.tailrec
def insert(t: IntTree, x: Int, parents: List[Node]): Node = t match {
case EmptyTree =>
parents.foldLeft(t insert x) { case (n, p) =>
if (p.elem >= n.elem) p.copy(left = n)
else p.copy(right = n)
}
case Node(data, l, r) =>
insert(if(data >= x) l else r, x, t :: parents)
}
insert(this, x, List.empty)
}

Related

Scala predicate composition

The java Predicate interface provides an or method that is used to combine multiple predicates. Example:
Predicate<Integer> p1;
Predicate<Integer> p2;
Predicate<Integer> p2 = p1.or(p2)
Since scala does not have the Predicate interface but uses Function1[A, Boolean] for this purpose what would be the best way to write this? Preferably without the use of external libraries.
I try to avoid the following:
val p1: (A => Boolean)
val p2: (A => Boolean)
val p3: (A => Boolean) = (a => p1(a) || p2(a))
You could provide the Predicate functionality in an implicit value class as
implicit class Predicate[A](val p1: A => Boolean) extends AnyVal {
def or[B >: A](p2: B => Boolean) = (a: A) => p1(a) || p2(a)
}
and then do
val gtOne = (x: Int) => x > 1
val ltMinusOne = (x: Int) => x < -1
val absGtOne = gtOne or ltMinusOne
absGtOne(-2) // true
absGtOne(0) // false
absGtOne(2) // true
You could provide an implicit conversion from A ⇒ Boolean to Predicate which supports the operations you want. Something like this:
implicit class Predicate[A](val p: A ⇒ Boolean) extends AnyVal {
type Predicate[A] = A ⇒ Boolean
def unary_! = (a: A) ⇒ !p(a)
def ==[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) == x(a)
def !=[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) != x(a)
def ||[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) || x(a)
def &&[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) && x(a)
def ^[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) ^ x(a)
def |[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) | x(a)
def &[B >: A](x: Predicate[B]) = (a: A) ⇒ p(a) & x(a)
}
This implements all the methods available in Boolean with the same semantics, e.g. Predicate.&& will only evaluate the second predicate if the first evaluates to true, whereas Predicate.| will always evaluate both predicates.
It's not part of the standard library, but if you only need simple expressions, you could:
Use the Java version, possibly using extension methods for syntactic sugar like p1 || p2 instead of p1.or(p2).
Roll your own case class Predicate[-A](p: A => Boolean) with a few simple methods like:
def ||[B <: A](other: Predicate[B]): Predicate[B] = ???
My stateful predicate:
/**
* Predicate logic with the state to print the function in natural language
*/
object StatefulPredicate {
class Predicate[E, T](predicate: E => T => Boolean, e: E, chain: Option[(Operator, Predicate[E, T])] = None) {
def test(t: T): Boolean = chain.map(c => c._1.execute(t, c._2.test(t), predicate(e))).getOrElse(predicate(e)(t))
def and(e: E): Predicate[E, T] = new Predicate[E, T](this.predicate, e, Some(AND, this))
def or(e: E): Predicate[E, T] = new Predicate[E, T](this.predicate, e, Some(OR, this))
override def toString: String = chain.map(c => c._2.toString + " " + c._1.toString + " " + e.toString).getOrElse(e.toString)
}
sealed trait Operator {
def execute[T](t: T, op1: Boolean, op2: T => Boolean): Boolean
}
case object AND extends Operator {
override def execute[T](t: T, op1: Boolean, op2: T => Boolean): Boolean = op1 && op2(t)
override def toString: String = "and"
}
case object OR extends Operator {
override def execute[T](t: T, op1: Boolean, op2: T => Boolean): Boolean = op1 || op2(t)
override def toString: String = "or"
}
def main(args: Array[String]): Unit = {
val p1: Predicate[Int, Seq[Int]] = new Predicate(e => s => s.contains(e), 10)
val p2: Predicate[Int, Seq[Int]] = p1.or(25)
val p3: Predicate[Int, Seq[Int]] = p2.and(25)
val p4: Predicate[Int, Seq[Int]] = p3.and(40)
print(p4.test(Seq[Int](10, 20, 30, 40)))
}
}

Restricting Method Parameter to a Specific Type in Scala

I have a function that I would like it to be generic but restrict it to take a certain subtypes. To keep things simple, I want my function to just work on Long, Int, Float and Double. So here is what I have come up with:
def covariance[A](xElems: Seq[A], yElems: Seq[A]): A = {
val (meanX, meanY) = (mean(xElems), mean(yElems))
val (meanDiffX, meanDiffY) = (meanDiff(meanX, xElems), meanDiff(meanY, yElems))
((meanDiffX zip meanDiffY).map { case (x, y) => x * y }.sum) / xElems.size - 1
}
def mean[A](elems: Seq[A]): A = {
(elems.fold(_ + _)) / elems.length
}
def meanDiff[A](mean: A, elems: Seq[A]) = {
elems.map(elem => elem - mean)
}
Here is the method that I will use to check for the above mentioned types:
import scala.reflect.{ClassTag, classTag}
def matchList2[A : ClassTag](list: List[A]) = list match {
case intlist: List[Int #unchecked] if classTag[A] == classTag[Int] => println("A List of ints!")
case longlist: List[Long #unchecked] if classTag[A] == classTag[Long] => println("A list of longs!")
}
Notice that I'm using ClassTag. I can also use a TypeTag and perhaps even the Shapeless library.
I would like to know if this is a good approach? Or should I use bounded types to solve what I want?
EDIT: Based on the comment and suggestion to use the Fractional Typeclass, here is how I think it could work!
def covariance[A: Fractional](xElems: Seq[A], yElems: Seq[A]): A = {
val (meanX, meanY) = (mean(xElems), mean(yElems))
val (meanDiffX, meanDiffY) = (meanDiff(meanX, xElems), meanDiff(meanY, yElems))
((meanDiffX zip meanDiffY).map { case (x, y) => x * y }.sum) / xElems.size - 1
}
def mean[A](elems: Seq[A]): A = {
(elems.fold(_ + _)) / elems.length
}
def meanDiff[A](mean: A, elems: Seq[A]) = {
elems.map(elem => elem - mean)
}
Based on the comments and inputs, here is what I came up with!
def mean[A](xs: Seq[A])(implicit A: Fractional[A]): A =
A.div(xs.sum, A.fromInt(xs.size))
def covariance[A](xs: Seq[A], ys: Seq[A])(implicit A: Fractional[A]): A = {
val (meanX, meanY) = (mean(xs), mean(ys))
val (meanDiffX, meanDiffY) = (meanDiff(meanX, xs), meanDiff(meanY, ys))
(meanDiffX zip meanDiffY).map { case (x, y) => A.div(A.times(x, y), A.fromInt(xs.size - 1)) }.sum
}
def meanDiff[A](mean: A, elems: Seq[A])(implicit A: Fractional[A]): Seq[A] = {
elems.map(elem => A.minus(elem, mean))
}

compiler error message when using State monad for memoization

I have a problem to make a working version of the Euler project problem 31 with the use of State trait (inspired from scalaz)
First, I have a solution with a mutable HashMap for memoization. It works but i would like to use the State monad, to understand it and to improve my skills.
I have used it with the fibonacci example, but when i attempt to apply the same technique to my case, i have a compiler error that i don't understand.
I use this implementation for State :
trait State[S, A] {
val run: S => (S, A)
def apply(s: S): (S, A) = run(s)
def eval(s: S): A = run(s)._2
def map[B](f: A => B): State[S, B] =
State { s: S =>
val (s1, a) = run(s)
(s1, f(a))
}
def flatMap[B](f: A => State[S, B]): State[S, B] =
State { s: S =>
val (s1, a) = run(s)
f(a)(s1)
}
}
object State {
def apply[S, A](f: S => (S, A)): State[S, A] = new State[S, A] {
final val run = f
}
def init[S, A](a: A) = State { s: S => (s, a) }
def update[S, A](f: S => S): State[S, Unit] = State { s: S => (f(s), ()) }
def gets[S, A](f: S => A): State[S, A] = State { s: S => (s, f(s)) }
}
my attempt to use it is here :
val coins = List(1, 2, 5, 10, 20, 50, 100, 200)
type MemoKey = (List[Int], Int)
type MemoType = Map[MemoKey, Int]
def ways(listCoins: List[Int], amount: Int): Int = {
def ways_impl(coins: List[Int], sum: Int): State[MemoType, Int] = (coins, sum) match {
case (Nil, 0) => State.init(1)
case (Nil, _) => State.init(0)
case (c :: cs, _) =>
for {
memoed <- State.gets { m: MemoType => m.get((coins, sum)) }
res <- memoed match {
case Some(way) => State.init[MemoType, Int](way)
case None =>
(for {
i <- 0 to sum / c
r <- ways_impl(cs, sum - i * c)
_ <- State.update { m: MemoType => m + ((coins, sum) -> r) }
} yield r).sum
}
} yield res
}
ways_impl(listCoins, amount) eval (Map())
I have a compiler error at this line :
r <- ways_impl(cs, sum - i * c)
The compiler said :
type mismatch; found : State[MemoType,Int] (which expands to) State[scala.collection.immutable.Map[(List[Int], Int),Int],Int] required: scala.collection.GenTraversableOnce[?]
For information, here is my first version with mutable map :
import scala.collection.mutable._
val memo = HashMap[(List[Int], Int), Int]()
val coins = List(1, 2, 5, 10, 20, 50, 100, 200)
def memoWays(coins: List[Int], sum: Int): Int = {
memo.getOrElse((coins, sum), {
val y = ways(coins, sum)
memo += ((coins, sum) -> y)
y
})
}
// brute force method with memoization
def ways(coins: List[Int], sum: Int): Int = (coins, sum) match {
case (Nil, 0) => 1
case (Nil, _) => 0
case (c :: cs, n) =>
(for {
i <- 0 to n / c
r = memoWays(cs, n - i * c)
} yield r).sum
}
println(s"result=${Mesure(ways(coins, 200))}")
What does that error mean ? Why the compiler want a GenTraversableOnce instead of State ?
What kind of thing i don't understand on State monad ?
And, if i may, I have an optional question :
Is my way to memoize with State Monad, is a good choice, or my first implementation with mutable map is better anyway ?
The problem is that your for comprehension is attempting to flatMap two unrelated types: a Range and a State. You're going to have to refactor, although off the top of my head, it's not clear to me how you'll be able to leverage State in a simple way. I'd probably use an immutable Map for the memo, a List to represent the future iterations to be tried, and simple recursion to iterate.

Tail recursive functions for BinaryTree

I am stuck with implementing tail recursive foreach, reduce, map and toList functions for a very simple implementation of binary tree.
sealed trait Tree[+A]
case object EmptyTree extends Tree[Nothing]
case class Node[A](value: A, left: Tree[A], right: Tree[A]) extends Tree[A]
object Tree {
def apply[A]: Tree[A] = EmptyTree
def apply[A](value: A): Tree[A] = Node(value, EmptyTree, EmptyTree)
def apply[A](value: A, left: Tree[A], right: Tree[A]): Tree[A] = Node(value, left, right)
def foreach[A](tree: Tree[A], f: (A) => Unit): Unit = {
//#tailrec
def iter[A](tree: Tree[A], f: (A) => Unit): Unit = tree match {
case EmptyTree =>
case Node(v, l, r) =>
iter(l, f)
f(v)
iter(r, f)
}
iter(tree, f)
}
def reduce[A](tree: Tree[A], value: A, f: (A, A) => A): A = {
//#tailrec
def loop(tree: Tree[A], value: A): A = tree match {
case Node(v, l, r) => loop(l, f(loop(r, value), v))
case EmptyTree => value
}
loop(tree, value)
}
def map[A, B](tree: Tree[A], f: A => B): Tree[B] = {
//#tailrec
def iter[A](tree: Tree[A], f: A => B): Tree[B] = tree match {
case Node(v, l, r) => Node(f(v), iter(l, f), iter(r, f))
case EmptyTree => EmptyTree
}
iter(tree, f)
}
def toList[A](t: Tree[A]): List[A] = {
//#tailrec
def iter[A](t: Tree[A]): List[A] = t match {
case Node(v, l, r) => v :: iter(l) ::: iter(r)
case EmptyTree => List.empty
}
iter(t)
}
}
Code for testing:
val tree = Tree(1, Tree(2, Tree(3), Tree(4)), Tree(5, Tree(6), Tree(7)))
Tree.foreach(tree, (x: Int) => println(x))
Tree.reduce(tree, 0, (x: Int, y: Int) => x + y)
Tree.map(tree, (x: Int) => x + 1)
Tree.toList(tree)
I cant use #tailrec attribute because as you can see, recursive calls are not the last calls in a function, and I do not know how to rewrite it because there are several calls in one function, for example
v :: iter(l) ::: iter(r)
I know that I can use accumulator for inner recursive functions but how I should use it in case of several calls ?
Thanks in advance.
Updated:
def toListRec[A](tree: Tree[A]): List[A] = {
#tailrec
def iter(result: List[A], todo: List[Tree[A]]): List[A] = todo match {
case x :: tail => x match {
case Node(v, l, r) => iter(v :: result, l :: r :: tail)
case EmptyTree => iter(result, tail)
}
case Nil => result.reverse
}
iter(List.empty, List(tree))
}
Without tail recursion, a(/the) stack is used to keep track of calling functions. If you want to use tail recursion, you'll have to find a way to keep track of this information elsewhere. In simpler "linear" cases, such as factorial, this information is pretty limited and can often easily be taken care of by using an accumulator.
In your case, the problem is that the recursion isn't linear. After one recursive call, the function doesn't just compute the result, but it makes another recursive call before being able to get to the result.
In order to apply tail recursion in this case, you will have to explicitly keep track of the remaining recursive calls that have to be made. An easy way is to simply keep a "to-do" list. For example:
def toList[A](t: Tree[A]): List[A] = {
#tailrec def iter[A](todo: List[Tree[A]], r: List[A]): List[A] =
todo match {
case t :: rest => t match {
case Node(v, l, r) => iter(l :: r :: rest, v :: r)
case EmptyTree => iter(rest, r)
}
case List.empty => reverse(r)
}
iter(List(t), List.empty)
}
Disclaimer: I know nothing about scala. :)
The solution that mweerden suggests would work, however, there is another way of solving the problem, which I think is much more elegant. Here is the code which traverses a tree to list
def toList[T](t: Tree[T]): List[T] = {
def tailRecursive(tree: Tree[T], acc: List[T]): List[T] = tree match {
case EmptyTree => acc
case Node(value, right, left) =>
tailRecursive(left, value :: tailRecursive(right, acc))
}
tailRecursive(t, List())
}
The solution implies that the tree is a binary search tree, and the list produced will be in ascending order (if the ascending order is not required, 6th line can be changed, putting the value in front of first recursive call or straightly into the accumulator would be possible).

Use Cons operator for a custom trait

I have a MyStream-trait:
trait MyStream[+A] {
def uncons: Option[(A, MyStream[A])]
def isEmpty: Boolean = uncons.isEmpty
}
object MyStream {
def empty[A]: MyStream[A] =
new MyStream[A] { def uncons = None }
def cons[A](hd: => A, tl: => MyStream[A]): MyStream[A] =
new MyStream[A] { lazy val uncons = Some((hd, tl)) }
def apply[A](as: A*): MyStream[A] = if (as.isEmpty) empty
else cons(as.head, apply(as.tail: _*))
}
How can I use the uncons operator for pattern matching like:
def takeWhile(f: A => Boolean): MyStream[A] = this match {
case uncons(h,t) if f(h()) => cons(h(), t() takeWhile f)
case _ => empty
}
I am very new to Scala so I need a little help here.
Thanks!
How about this:
trait MyStream[+A] {
def uncons: Option[(A, MyStream[A])]
def isEmpty: Boolean = uncons.isEmpty
def takeWhile(f: A => Boolean): MyStream[A] = this match {
case MyStream(h, t) if f(h) => MyStream.cons(h, t takeWhile f)
case _ => MyStream.empty
}
#tailrec
final def foldLeft[B](z: B)(op: (B, A) => B): B =
this match {
case MyStream(h, t) => t.foldLeft(op(z, h))(op)
case _ => z
}
override def toString = this.foldLeft("") { case (acc, x) => acc + x }
}
object MyStream {
def empty[A]: MyStream[A] =
new MyStream[A] {
def uncons = None
}
def cons[A](hd: => A, tl: => MyStream[A]): MyStream[A] =
new MyStream[A] {
lazy val uncons = Some((hd, tl))
}
def apply[A](as: A*): MyStream[A] =
if (as.isEmpty) empty
else cons(as.head, apply(as.tail: _*))
def unapply[A](stream: MyStream[A]) = stream.uncons
}
object TestMyStream extends App {
import MyStream._
val s = cons(1, cons(2, cons(3, empty)))
println("All: " + s)
println("Take < 3: " + s.takeWhile(_ < 3))
}
prints:
All: 123
Take < 3: 12