Ramy
Ramy

Reputation: 21271

scala pattern matching

It seems the type of Nil is not polymorphic. How do I correct this function:

scala> def last[A](a:List[A]) : A =   
     | a match {                      
     |   case _ :: tail  => last(tail)
     |   case Nil => Nil[A]           
     | }                              
<console>:8: error: object Nil does not take type parameters.
     case Nil => Nil[A]

UPDATE:

scala> def last[A](a : List[A] ) : Option[A] =
     | a match {                              
     |   case head :: Nil => Some(head)       
     |   case _ :: tail => last(tail)  
     |   case Nil => None                     
     | }                                      

Upvotes: 2

Views: 741

Answers (4)

Landei
Landei

Reputation: 54584

The object Nil extends List[Nothing]. Nothing is a sub-type of everything (similar as Any is the super-type of everything), and List is covariant (denoted as List[+A]), which means that Nil will fit as endpoint for every list.

However, as a result of this construction, there are situations where the compiler can't infer the correct type of an empty list, and you need to give a hint (as shown by Ben James). BTW, the same applies to the object None as sub-class of Option.

Upvotes: 0

missingfaktor
missingfaktor

Reputation: 92096

Nil is an object, not a type. So Nil[A] doesn't make any sense.

An empty list does not have a last element. As such invoking last on Nil should throw an error.

def last[A](l: List[A]): A = l match {                      
  case x :: Nil => x
  case _ :: tail => last(tail)
  case Nil => sys.error("An empty list")
} 

Alternatively you could have last return an Option[A] as shown below:

def last[A](l: List[A]): Option[A] = l match {                      
  case x :: Nil => Some(x)
  case _ :: tail => last(tail)
  case Nil => None
} 

Upvotes: 4

aioobe
aioobe

Reputation: 421180

The error is that you've declared the method to return A:

def last[A](a:List[A]) : A
                        ^^^

and the empty list, Nil is not an A.

(And (as a side-note), as the error message says, Nil does not take type parameters.)


A better return type for a last function is probably Option[A]. Your method definition, but with Option[A] would look like:

scala> def last[A](a: List[A]): Option[A] =
     | a match {                           
     |     case x :: Nil => Some(x)        
     |     case _ :: tail => last(tail)    
     |     case Nil => None                
     | }                                   
last: [A](a: List[A])Option[A]

Upvotes: 1

Ben James
Ben James

Reputation: 125257

When you need to tell the compiler what type Nil should be, you can use type ascription, like this:

Nil: List[A]

But, as aioobe pointed out, this won't solve your problem. Nil is an empty list, not the last element of a list.

Upvotes: 0

Related Questions