user3316676
user3316676

Reputation: 109

Can Scala Option class be used as a function argument?

I have a recursive function which collects the leaf nodes of a kd-tree. This function has to take KdNode as an argument. The KdNode has the following class definition:

case class KdNode(value: (Double, Double), left: Option[KdNode], right: Option[KdNode], axis: Int, BB_A:BoundingBox, BB_B:BoundingBox)

The function definition where it is taken as an argument is:

def collectLeafNodes(t:KdNode): List[BoundingBox] = {
if(t == None) return
if (t.left == None && t.right == None) {
  Some(listBoundingBox.::(t.BB_A,t.BB_B))
  return
}
collectLeafNodes(t.left)
collectLeafNodes(t.right)}

Here, I encounter error on the last 2 lines saying: "Type mismatch, expected: KdNode, actual: Option[KdNode].

I am calling this function by building the kd-tree in variable "tree" and giving it as an argument:

val listofBoundingBoxes=collectLeafNodes(tree)

What is a possible workaround in this situation? In addition, I think there should be a way to pass the root node instead of tree to the collectLeafNodes function, is that possible given the tree is built in a separate function.

Thanks.

Upvotes: 0

Views: 67

Answers (3)

jwvh
jwvh

Reputation: 51271

You ask, in the comments, how it can be done without return. Here's one way.

def collectLeafNodes(t :KdNode) :List[BoundingBox] =
  List(t.BB_A, t.BB_B) :::
    t.left.fold(List.empty[BoundingBox])(collectLeafNodes) :::
    t.right.fold(List.empty[BoundingBox])(collectLeafNodes)

The result, without return, is the concatenation of 3 lists:

  1. Since t is a KdNode and not an Option[KdNode], we know that the the BB values are real. That's the 1st List.
  2. If t.left is None then the 2nd List is empty, otherwise the 2nd List is whatever the recursive call to collectLeafNodes(t.left) returns. (The argument is automatically supplied so it need not be specified.)
  3. Same for the 3rd List with t.right

corrected for leaf nodes only

def collectLeafNodes(t :KdNode) :List[BoundingBox] = {
  if (t.left.isEmpty && t.right.isEmpty) List(t.BB_A, t.BB_B)
  else t.left .fold(List.empty[BoundingBox])(collectLeafNodes) :::
       t.right.fold(List.empty[BoundingBox])(collectLeafNodes)
}

Upvotes: 3

senjin.hajrulahovic
senjin.hajrulahovic

Reputation: 3191

You can map over the option object:

val res: List[BoundingBox] = t.left.map(collectLeafNodes).getOrElse(List())

Upvotes: 2

Himanshu Ahire
Himanshu Ahire

Reputation: 717

Because t.right is type of Option and not type of Kdnode.

You can unwrap Option to solve this e.g.

collectLeafNodes(t.right.get)}
collectLeafNodes(t.right.orElse(None)}

Hope this helps

Upvotes: 0

Related Questions