def third_list[A](ls: List[A]): A = {
// Code can be changed here
return List(ls(2)) //Error line for return type
}
val l1 = List(1, 2, 3, 4)
println(third_list(l1))
println(third_list(List(1,2,(3,4,5), 6, 7)))
I need to return 3rd element of the list following the return type criteria.
I am getting type mismatch error:
Required A found list[A]
Shouldn't ls(2) return an element type already?
CodePudding user response:
The simple answer to the question is to use lift
:
def third_list[A](ls: List[A]): Option[A] =
ls.lift(2)
This returns an Option
because you really want your code to work even if the list doesn't have three elements. Process the data inside the Option
or use getOrElse
to specify a default.
CodePudding user response:
You are returning a List with elements of type A therefore you are returning a List[A] value, but the return type you have set for that method is A and they do not match.
CodePudding user response:
You have declared the return type of third_list
as A
, but you are extracting an element of type A
(ls(2)
), wrapping it in a new list (List(ls(2))
, and returning that instead. Also, your code will fail if there aren't at least 3 elements in your list. One way to handle that could be to return an Option[A]
rather than an A
. Something like the following:
def third_list[A](ls: List[A]): Option[A] = ls match {
case _ :: _ :: third :: _ =>
Some(third)
case _ =>
None
}
Edit:
Using Option
to handle the scenario where the third element isn't present is the ideal approach as it tells the caller of this method that it cannot be guarateed to return a value of A
.
If, however, you have to keep the original method signature you could throw an exception in the event that a third element is not present:
def third_list[A](ls: List[A]): A = ls match {
case _ :: _ :: third :: _ =>
third
case _ =>
throw new RuntimeException(s"Error occurred access third element of list. List had length ${ls.length}.")
}
Alternatively could ask the caller of method to provide a default value in the event a third element is no accessible, though in this scenario you are again changing the method signature, and therefore Option
is recommended:
def third_list[A](ls: List[A], default: => A): A = ls match {
case _ :: _ :: third :: _ =>
third
case _ =>
default
}
It worth repeating that having the return type be of type Option
is still the best practice approach. See this official Scala lang documentation on functional error handling.