斯卡拉模式匹配

时间:2011-08-07 20:18:40

标签: scala

似乎Nil的类型不是多态的。如何更正此功能:

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]

更新:

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

4 个答案:

答案 0 :(得分:4)

Nil是一个对象,而不是一个类型。所以Nil[A]没有任何意义。

空列表没有最后一个元素。因此,在last上调用Nil会引发错误。

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

或者,您可以last返回Option[A],如下所示:

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

答案 1 :(得分:1)

错误是您已声明方法返回A

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

且空列表Nil不是A

(并且(作为旁注),正如错误消息所示,Nil不接受类型参数。)


last函数的更好返回类型可能是Option[A]。您的方法定义,但使用Option[A]看起来像:

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]

答案 2 :(得分:0)

当你需要告诉编译器{/ 1}}应该是什么类型时,可以使用类型ascription,如下所示:

Nil

但是,正如aioobe指出的那样,这不会解决你的问题。 Nil: List[A] 是一个空列表,而不是列表的最后一个元素。

答案 3 :(得分:0)

对象Nil扩展List[Nothing]Nothing是所有内容的子类型(类似于Any是所有内容的超类型),List是协变的(表示为List[+A]),这意味着Nil将适合作为每个列表的端点。

但是,由于这种结构,有些情况下编译器无法推断出空列表的正确类型,您需要提示(如Ben James所示)。顺便说一下,对象None同样适用于Option的子类。