Reputation: 35
Why is this function giving me the following error:
recursive value listHuman needs type
def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
val listHuman = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post)).filterNot(a=>listHuman.contains(a))}
return listHuman
}
I tried to do this, but it gives me another error:
val listHuman: List[Human] = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post)).get}.filterNot(human=>listHuman.contains(human))
forward reference extends over definition of value listHuman
Upvotes: 0
Views: 2682
Reputation: 11577
The premises here is to have setHumanResources
return a unique/distint list of Human
objects. The code tries this by doing filterNot(a=>listHuman.contains(a))
in definition of listHuman
and thus recursively referring to listHuman
while defining listHuman
in semantically illegal way. This de-duping can be achieved properly by the following ways.
convert the List to Set and convert it back to List to remove duplicates like listHuman.toSet.ToList
. for this method to work the Human object have property identity defined by overriding equals
method. so the code will now look like
def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
val listHuman = physicalResources.map{pr => totalHumanResources.find(_.handles.contains(pr.post))
listHuman.toSet.toList
}
A Demo for a sample class of Human is shown below.
scala> class Human(val firstName: String, val lastName: String) {
| override def toString = this.firstName
| override def equals(that: Any): Boolean = that match {
| case that: Human if that.firstName == this.firstName => true
| case _ => false
| }
| }
defined class Human
scala> List(new Human("Peter", "Parker"), new Human("Peter", "Quill")).toSet.toList
res14: List[Human] = List(Peter)
If the class Human
cannot have object equality defined in it by overriding equals method then follow this approach. considering each Human
can be uniquely identified by say two properties property1
and property2
. the listHuman can be deduped by the following expression. For our previously defined Human
class if we want to de-dupe on both firstName and lastName properties, the code would be like below.
listHuman.groupBy(x => (x.firstName, x.lastName)).map(_._2.head)
so the new method definition becomes
def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
val listHuman = physicalResources.map{pr =>
totalHumanResources.find(_.handles.contains(pr.post))
listHuman.groupBy(x => (x.property1, x.property2) ).map(_._2.head)
}
Upvotes: 0
Reputation: 2452
It seems like you want to do a foldLeft
, does this work?
def setHumanResources(physicalResources: List[Physical], totalHumanResources: List[Human]): List[Human] = {
physicalResources.foldLeft(Set.empty[Human]) { (l, pr) =>
val applicableHuman = totalHumanResources.find(_.handles.contains(pr.post))
l ++ applicableHuman
}.toList
}
Upvotes: 1
Reputation: 1766
This error means that constant value or variable is used before its declaration. For example
val y = x + 2
val x = 5
What wrong with your code is you try to define constant value with itself. It's impossible by definition of constant
. To build recursion use def
.
Upvotes: 1