ScalaCheck generate BST - scala

I'm trying to create a Gen for BST with ScalaCheck, but when I call .sample method it gives me java.lang.NullPointerException. Where do I wrong?
sealed trait Tree
case class Node(left: Tree, right: Tree, v: Int) extends Tree
case object Leaf extends Tree
import org.scalacheck._
import Gen._
import Arbitrary.arbitrary
case class GenerateBST() {
def genValue(left: Tree, right: Tree): Gen[Int] = (left, right) match {
case (Node(_, _, min), Node(_, _, max)) => arbitrary[Int].suchThat(x => x > min && x < max)
case (Node(_, _, min), Leaf) => arbitrary[Int].suchThat(x => x > min)
case (Leaf, Node(_, _, max)) => arbitrary[Int].suchThat(x => x < max)
case (Leaf, Leaf) => arbitrary[Int]
}
val genNode = for {
left <- genTree
right <- genTree
v <- genValue(left, right)
} yield Node(left, right, v)
def genTree: Gen[Tree] = oneOf(const(Leaf), genNode)
}
GenerateBST().genTree.sample

Because of the way you're defining the generator recursively for a recursive data type, you need to use Gen.lzy at the top:
def genTree: Gen[Tree] = Gen.lzy(oneOf(const(Leaf), genNode))
As an unrelated side note, using suchThat in your generator definitions should generally only be a last resort. It means that sample will often fail (about a third of the time with the fixed version of your code), and more importantly that if you someday want to create arbitrary functions resulting in Tree, you're going to see a lot of horrible org.scalacheck.Gen$RetrievalError: couldn't generate value exceptions.
In this case you can avoid suchThat pretty easily by using Gen.chooseNum and swapping the left and right sides if they're in the wrong ordered:
sealed trait Tree
case class Node(left: Tree, right: Tree, v: Int) extends Tree
case object Leaf extends Tree
import org.scalacheck.{ Arbitrary, Gen }
object GenerateBST {
def swapIfNeeded(l: Tree, r: Tree): (Tree, Tree) = (l, r) match {
// If the two trees don't have space between them, we bump one and recheck:
case (Node(_, _, x), n # Node(_, _, y)) if math.abs(x - y) <= 1 =>
swapIfNeeded(l, n.copy(v = y + 1))
// If the values are in the wrong order, swap:
case (Node(_, _, x), Node(_, _, y)) if x > y => (r, l)
// Otherwise do nothing:
case (_, _) => (l, r)
}
def genValue(left: Tree, right: Tree): Gen[Int] = (left, right) match {
case (Node(_, _, min), Node(_, _, max)) => Gen.chooseNum(min + 1, max - 1)
case (Node(_, _, min), Leaf) => Gen.chooseNum(min + 1, Int.MaxValue)
case (Leaf, Node(_, _, max)) => Gen.chooseNum(Int.MinValue, max - 1)
case (Leaf, Leaf) => Arbitrary.arbitrary[Int]
}
val genNode = for {
l0 <- genTree
r0 <- genTree
(left, right) = swapIfNeeded(l0, r0)
v <- genValue(left, right)
} yield Node(left, right, v)
def genTree: Gen[Tree] = Gen.lzy(Gen.oneOf(Gen.const(Leaf), genNode))
}
Now you can use Arbitrary[Whatever => Tree] without worrying about generator failures:
scala> implicit val arbTree: Arbitrary[Tree] = Arbitrary(GenerateBST.genTree)
arbTree: org.scalacheck.Arbitrary[Tree] = org.scalacheck.ArbitraryLowPriority$$anon$1#606abb0e
scala> val f = Arbitrary.arbitrary[Int => Tree].sample.get
f: Int => Tree = org.scalacheck.GenArities$$Lambda$7109/289518656#13eefeaf
scala> f(1)
res0: Tree = Leaf
scala> f(2)
res1: Tree = Node(Leaf,Leaf,-20313200)
scala> f(3)
res2: Tree = Leaf
scala> f(4)
res3: Tree = Node(Node(Leaf,Leaf,-850041807),Leaf,-1)

Related

Functional composition of both success and error paths

TLDR: I'm looking for functional programming patterns for composing both the success and failure paths of recursive, failable functions.
Scastie link for the example code: https://scastie.scala-lang.org/apUioyJsSdaziPfiE14CoQ
Given a recursive datatype and failable method that operates on it:
sealed trait Expr
case class Lit(x: Int) extends Expr
case class Div(lhs: Expr, rhs: Expr) extends Expr
def evaluate(expr: Expr): Either[String, Int] = ???
Typical examples of functional composition show how to elegantly implement these things:
def evaluate(expr: Expr): Either[String, Int] = expr match {
case Lit(x) => Right(x)
case Div(l, r) =>
for {
x <- evaluate(l)
y <- evaluate(r)
res <- if (y != 0) Right(x / y) else Left("Divide by 0!")
} yield res
}
evaluate(Div(Lit(8), Div(Lit(3), Lit(0)))) // Left("Divide by 0!")
This is great, except that sometimes you also want to do some kind of composition of the error messages. This is especially useful if you want parent nodes to add information to errors propagated from their children.
Perhaps I want to return an error message with context about the entire expression rather than just the information that there was a divide by 0 somewhere:
def evaluate2(expr: Expr): Either[String, Int] = expr match {
case Lit(x) => Right(x)
case Div(lhs, rhs) =>
val l = evaluate2(lhs)
val r = evaluate2(rhs)
val result = for {
x <- l
y <- r
res <- if (y != 0) Right(x / y) else Left(s"$x / 0")
} yield res
result.orElse {
Left(s"(${l.merge}) / (${r.merge})") // take advantage of Any.toString
}
}
evaluate2(Div(Lit(8), Div(Lit(3), Lit(0)))) // Left("(8) / (3 / 0)")
This isn't terrible, but it isn't great either. It's 4 lines of business logic vs. 5-6 of boiler plate.
Now, I'm not the best at functional programming, and I don't know much about Cats and Scalaz, but I do now that this smells like a reusable higher-order function. From the type that I want, I can derive a pretty useful utility function:
def flatMap2OrElse[R, A, B](x: Either[R, A], y: Either[R, A])
(f: (A, A) => Either[R, B])
(g: (Either[R, A], Either[R, A]) => R): Either[R, B] =
(x, y) match {
case (Right(a), Right(b)) => f(a, b)
case _ => Left(g(x, y))
}
Then it's trivial to write a concise form:
def evaluate3(expr: Expr): Either[String, Int] = expr match {
case Lit(x) => Right(x)
case Div(lhs, rhs) =>
flatMap2OrElse(evaluate3(lhs), evaluate3(rhs)) {
(x, y) => if (y != 0) Right(x / y) else Left(s"$x / 0")
} {
(x, y) => s"(${x.merge}) / (${y.merge})"
}
}
evaluate3(Div(Lit(8), Div(Lit(3), Lit(0)))) // Left("(8) / (3 / 0)")
The orElse function taking Eithers is a bit weird, but it's my function and it can be weird if I want it to.
In any case, it seems to me that there should be a pattern here. Is the style of evaluate2 the canonical way of doing it or are there utilities/abstractions I should be looking at to better handle this kind of thing?
EDIT
New Scastie: https://scastie.scala-lang.org/p0odf16PTLOTJPYSF9CGMA
This is a partial answer, but still requires a custom function that feels like it should exist somewhere. I think with just flatMap2 we can do this pretty clearly without the boutique flatMap2OrElse:
def flatMap2[R, A, B](x: Either[R, A], y: Either[R, A])
(f: (A, A) => Either[R, B]): Either[R, B] =
(x, y) match {
case (Right(a), Right(b)) => f(a, b)
case (Left(a), _) => Left(a) // Need Either[R, B]
case (_, Left(b)) => Left(b)
}
def evaluate4(expr: Expr): Either[String, Int] = expr match {
case Lit(x) => Right(x)
case Div(lhs, rhs) =>
val l = evaluate4(lhs)
val r = evaluate4(rhs)
flatMap2(l, r)((x, y) => if (y != 0) Right(x / y) else Left(s"$x / 0"))
.orElse(Left(s"(${l.merge}) / (${r.merge})"))
}
evaluate4(Div(Lit(8), Div(Lit(3), Lit(0)))) // Left("(8) / (3 / 0)")
That being said, this concept should generalize beyond flatMap2. It just feels like this is already a thing.

Filter from Seq less/greater elements and only one equal

I want to implement method in Scala which filters from Seq elements which are for example greater than provided value and additionally returns up to one equal element. For example:
greaterOrEqual(Seq(1,2,3,3,4), 3) shouldBe Seq(3,4)
I ended up with such method:
def greaterOrEqual(
seq: ArrayBuffer[Long],
value: Long
): ArrayBuffer[Long] = {
val greater = seq.filter(_ > value)
val equal = seq.filter(_ == value)
if (equal.isEmpty) {
greater
} else {
equal.tail ++ greater
}
}
but somehow it doesn't look nice to me :) Moreover, I'd like to have generic version of this method where I'd able to use not only Long type but custom case classes.
Do you have any suggestions?
Thanks in advance.
def foo[A : Ordering[A]](seq: Seq[A], value: A) = seq.find(_ == value).toList ++ seq.filter(implicitly[Ordering[A]].gt(_,value))
Or (different style)
def foo[A](seq: Seq[A], value: A)(implicit ord: Ordering[A]) = {
import ord._
seq.find(_ == value).toList ++ seq.filter(_ > value)
}
The code below is deprecated
scala> def foo[A <% Ordered[A]](seq: Seq[A], value: A) = seq.find(_ == value).toList ++ seq.filter(_ > value)
foo: [A](seq: Seq[A], value: A)(implicit evidence$1: A => Ordered[A])List[A]
scala> foo(Seq(1,2,3,3,4,4,5),3)
res8: List[Int] = List(3, 4, 4, 5)
Here's my take on it (preserving original order).
import scala.collection.mutable.ArrayBuffer
def greaterOrEqual[A]( seq :ArrayBuffer[A], value :A
)(implicit ord :Ordering[A]
) : ArrayBuffer[A] =
seq.foldLeft((ArrayBuffer.empty[A],true)){
case (acc, x) if ord.lt(x,value) => acc
case ((acc,bool), x) if ord.gt(x,value) => (acc :+ x, bool)
case ((acc,true), x) => (acc :+ x, false)
case (acc, _) => acc
}._1
testing:
greaterOrEqual(ArrayBuffer.from("xawbaxbt"), 'b')
//res0: ArrayBuffer[Char] = ArrayBuffer(x, w, b, x, t)
This is an excellent problem for a simple tail-recursive algorithm over lists.
def greaterOrEqual[T : Ordering](elements: List[T])(value: T): List[T] = {
import Ordering.Implicits._
#annotation.tailrec
def loop(remaining: List[T], alreadyIncludedEqual: Boolean, acc: List[T]): List[T] =
remaining match {
case x :: xs =>
if (!alreadyIncludedEqual && x == value)
loop(remaining = xs, alreadyIncludedEqual = true, x :: acc)
else if (x > value)
loop(remaining = xs, alreadyIncludedEqual, x :: acc)
else
loop(remaining = xs, alreadyIncludedEqual, acc)
case Nil =>
acc.reverse
}
loop(remaining = elements, alreadyIncludedEqual = false, acc = List.empty)
}
Which you can use like this:
greaterOrEqual(List(1, 3, 2, 3, 4, 0))(3)
// val res: List[Int] = List(3, 4)
You can use the below snippet:
val list = Seq(1,2,3,3,4)
val value = 3
list.partition(_>=3)._1.toSet.toSeq
Here partition method divide the list into two list. First list which satisfy the given condition, and second list contains the remaining elements.
For generic method you can using implicit Ordering. Any type who can compare elements can be handled by greaterOrEqual method.
import scala.math.Ordering._
def greaterOrEqual[T](seq: Seq[T], value: T)(implicit ordering: Ordering[T]): Seq[T] = {
#scala.annotation.tailrec
def go(xs: List[T], value: T, acc: List[T]): List[T] = {
xs match {
case Nil => acc
case head :: rest if ordering.compare(head, value) == 0 => rest.foldLeft(head :: acc){
case (result, x) if ordering.compare(x, value) > 0 => x :: result
case (result, _) => result
}
case head :: rest if ordering.compare(head, value) > 0 => go(rest, value, head :: acc)
case _ :: rest => go(rest, value, acc)
}
}
go(seq.toList, value, List.empty[T]).reverse
}

scala n-arity tree tail recursive evaluation

I have a Tree structure, which is more general than a binary tree structure
sealed trait Tree[+A]
case class Leaf[A](value: Terminal[A]) extends Tree[A]
case class Node[A](op: Function[A], branches: Tree[A]*) extends Tree[A]
As you see, it can have a arbitrary number of branches.
I'm trying to make an evaluation method to be tail recursive but i'm not being able to do it.
def evaluateTree[A](tree: Tree[A]): A = tree match {
case Leaf(terminal) => terminal.value
case Node(op: Function[A], args # _*) => op.operator((for (i <- args) yield evaluateTree(i)))
}
How can i save the stack manually?
If each Node can hold a different op then, no, I don't think tail recursion is possible.
If, on the other hand, you can feed all the Leaf.values to a single op then it might be possible.
def evaluateTree[A](tree: Tree[A]): A = {
#tailrec
def allValues(branches: Seq[Tree[A]], acc: Seq[A] = Seq()): Seq[A] =
if (branches.length < 1) acc
else branches.head match {
case Leaf(term) => allValues(branches.tail, term.value +: acc)
case Node(_, args: Seq[Tree[A]]) => allValues(branches.tail ++ args, acc)
}
tree match {
case Leaf(terminal) => terminal.value
case Node(op: Function[A], args: Seq[Tree[A]]) => op.operator(allValues(args))
}
}
I can't compile this as I don't have definitions for Terminal and Function, but it should be a reasonable outline of one approach to the problem.
Actually it was possible, using deep first search.
def evaluateTree[A](tree: Tree[A]): A = {
#tailrec
def evaluateWhile[C](l: List[Function[C]], arguments: List[List[C]], n_args: List[Int], f: Int => Boolean, acc: C): (List[Function[C]], List[List[C]], List[Int]) =
n_args match {
case h :: t if f(h) =>
evaluateWhile(l.tail, arguments.tail, n_args.tail, f, l.head.operator(arguments.head ::: List(acc)))
case h :: t =>
(l, (List(acc) ::: arguments.head) :: arguments.tail, List(n_args.head - 1) ::: n_args.tail)
case _ =>
(l, List(acc) :: arguments, n_args)
}
#tailrec
def DFS(toVisit: List[Tree[A]], visited: List[String] = Nil, operators: List[Function[A]] = Nil, arguments: List[List[A]] = Nil, n_args: List[Int] = Nil, debug: Int = 0): A = toVisit match {
case Leaf(id, terminal) :: tail if !visited.contains(id) => {
val (operators_to_pass, args_to_pass, n_args_to_pass) =
evaluateWhile[A](operators, arguments, n_args, x => x == 1, terminal.value)
DFS(toVisit.tail, visited ::: List(id), operators_to_pass, args_to_pass, n_args_to_pass, debug + 1)
}
case Node(id, op, args #_*) :: tail if !visited.contains(id) => {
DFS(args.toList ::: toVisit.tail, visited ::: List(id), op :: operators, List(Nil) ::: arguments, List(args.length ) ::: n_args, debug + 1)
}
case _ => arguments.flatten.head
}
DFS(List(tree))
}

Scala wrong forward reference

I am working through some of the exercises in: Functional Programming in Scala specifically problem 5.2. The issue is that with the following code which I have pieced together from the answer key.
sealed trait Stream[+A]
{
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => cons(h(), t().take(n - 1))
case Cons(hs, _) if n == 1 => cons(h(), empty)
case _ => empty
}
}
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]
object Stream{
def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = {
lazy val head = hd
lazy val tail = tl
Cons(() => head , () => tail)
}
def empty[A]: Stream[A] = Empty
def apply[A](as: A*): Stream[A] =
if (as.isEmpty) empty
else cons(as.head, apply(as.tail: _*))
}
I get the following in the REPL:
<console>:10: error: not found: type A
def take(n: Int): Stream[A] = this match {
^
<console>:11: error: not found: value Cons
case Cons(hs, ts) if n > 1 => cons(h(), t().take(n - 1))
^
<console>:11: error: not found: value cons
case Cons(hs, ts) if n > 1 => cons(h(), t().take(n - 1))
^
<console>:12: error: not found: value Cons
case Cons(hs, _) if n == 1 => cons(h(), empty)
^
<console>:12: error: not found: value cons
case Cons(hs, _) if n == 1 => cons(h(), empty)
^
<console>:13: error: not found: value empty
case _ => empty
^
You have 2 problems in this code:
Not explicitly specifying that the empty and cons methods are located in the companion object Stream
To fix this you need to either import Stream._ into your class:
sealed trait Stream[+A] {
import Stream._
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => cons(hs(), empty)
case _ => empty
}
}
Or you need to explicitly specify it:
sealed trait Stream[+A] {
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => Stream.cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => Stream.cons(hs(), Stream.empty)
case _ => Stream.empty
}
}
Using the variable names of t and h that are in case class Cons instead of the bound variables of hs and ts.
When you do this:
case Cons(hs, ts) if n > 1 => Stream.cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => Stream.cons(hs(), Stream.empty)
You are saying that you want to extract the case class parameters as hs and ts respectively and use them in the next code block. It does not matter if they were called h and t in the case class, they will be assigned the names you specify in the match.
Fixing these two issues and your code should compile (I personally tested it with Scala 2.11.5 and Java 1.7, but I don't think it should matter):
sealed trait Stream[+A] {
def take(n: Int): Stream[A] = this match {
case Cons(hs, ts) if n > 1 => Stream.cons(hs(), ts().take(n - 1))
case Cons(hs, _) if n == 1 => Stream.cons(hs(), Stream.empty)
case _ => Stream.empty
}
}
case object Empty extends Stream[Nothing]
case class Cons[+A](h: () => A, t: () => Stream[A]) extends Stream[A]
object Stream{
def cons[A](hd: => A, tl: => Stream[A]): Stream[A] = {
lazy val head = hd
lazy val tail = tl
Cons(() => head , () => tail)
}
def empty[A]: Stream[A] = Empty
def apply[A](as: A*): Stream[A] =
if (as.isEmpty) empty
else cons(as.head, apply(as.tail: _*))
}

Return a different type according to an input parameter

Let's see an example (it's a naive example but sufficient to illustrate the problem).
def produce(l: List[Int]) : Any =
l match {
case List(x) => x
case List(x, y) => (x, y)
}
val client1 : Int = produce(List(1)).asInstanceOf[Int]
Drawback : client need to cast !
def produce2[A](l: List[Int])(f: List[Int] => A) = {
f(l)
}
val toOne = (l: List[Int]) => l.head
val toTwo = (l: List[Int]) => (l.head, l.tail.head)
val client2 : Int = produce2(List(1))(toOne)
Drawback : type safety, i.e. we can call toTwo with a singleton List.
Is there a better solution ?
If you only have two possible return values you could use Either:
def produce(l : List[Any]) : Either[Any, (Any, Any)] = l match {
case List(x) => Left(x)
case List(x, y) => Right((x, y))
}
If you don't want to create an Either, you could pass a function to transform each case:
def produce[A](l : List[Int])(sf: Int => A)(pf: (Int, Int) => A): A = l match {
case List(x) => sf(x)
case List(x, y) => pf(x, y)
}
Will this work?
def produce(l: List[Int]) = {
l match {
case List(x) => (x, None)
case List(x,y) => (x,y)
case Nil => (None, None)
}
}
or even better, to avoid match errors on lists longer than 2 elements:
def produce(l: List[Int]) =
l match {
case x :: Nil => (x, None)
case x :: xs => (x,xs.head)
case Nil => (None, None)
}