The following doesn’t compile. Do I need to cast the person first?
object People {
def all = List(
new Person("Jack", 33),
new Person("John", 31) with Authority,
new Person("Jill", 21),
new Person("Mark", 43)
)
}
class Person(val name: String, val age: Int)
trait Authority {
def giveOrder {
println("do your work!")
}
}
object Runner {
def main(args:List[String]) {
val boss = People.all.find { _.isInstanceOf [Authority] }.get
boss.giveOrder // This line doesnt compile
}
}
You’re right thinking that somehow, there should be a mechanism that lets you avoid casting. Such a cast would be ugly and redundant, as it already appears in the filter anyway.
find, however, does not care at all about the shape of the predicate it gets; it just applies it and returns anOption[A]ifAis the static type of the collection’s elements.What you need is the
collectfunction:collectcreates a new collection. If you want to avoid this (if you’re really only interested in the first element which is of kindAuthority) in case of a potentially very long list of potential bosses, you may want to switch to aviewto have it evaluated lazily:Finally, unless you’re absolutely sure that there is always at least one boss in your list, you should really test whether or not the search was successful, e.g. like this:
Edit: Finally, if you’re using Scala 2.9, you should definitely use
collectFirstas explained in Kevin Wright’s answer.