为什么我不能在伴侣对象上调用函数?

时间:2015-11-25 02:38:20

标签: scala

在下面的代码中,为什么我在创建fpinscala.datastructures.List的实例时不能调用sum函数?即在SBT控制台中,我执行以下操作:

scala> :paste  -raw exercises/src/main/scala/fpinscala/datastructures/List.scala
scala> val list = fpinscala.datastructures.List(2,3)
scala> list.sum(fpinscala.datastructures.List(2,3))

我想我的问题是我不太了解伴侣对象 - 虽然我的理解是它只是在我创建的类型上定义了函数然后我可以调用它?

package fpinscala.datastructures                                                                                        

sealed trait List[+A] // `List` data type, parameterized on a type, `A`                                                 
case object Nil extends List[Nothing] // A `List` data constructor representing the empty list                          
/* Another data constructor, representing nonempty lists. Note that `tail` is another `List[A]`,                        
which may be `Nil` or another `Cons`.                                                                                   
 */                                                                                                                     
case class Cons[+A](head: A, tail: List[A]) extends List[A]                                                             

object List { // `List` companion object. Contains functions for creating and working with lists.                       
  def sum(ints: List[Int]): Int = ints match { // A function that uses pattern matching to add up a list of integers    
    case Nil => 0 // The sum of the empty list is 0.                                                                    
    case Cons(x,xs) => x + sum(xs) // The sum of a list starting with `x` is `x` plus the sum of the rest of the list.  
  }                                                                                                                     

  def product(ds: List[Double]): Double = ds match {                                                                    
    case Nil => 1.0                                                                                                     
    case Cons(0.0, _) => 0.0                                                                                            
    case Cons(x,xs) => x * product(xs)                                                                                  
  }                                                                                                                     

  def apply[A](as: A*): List[A] = // Variadic function syntax                                                           
    if (as.isEmpty) Nil                                                                                                 
    else Cons(as.head, apply(as.tail: _*)) 
}

编辑:也许更好的问题是,我将如何实施以下内容:

 scala> val list = fpinscala.datastructures.List(2,3)
 scala> list.sum (should return 5)  

2 个答案:

答案 0 :(得分:2)

首先,请注意这一行:

val list = fpinscala.datastructures.List(2,3)

与以下内容相同:

val list = fpinscala.datastructures.List.apply(2,3)

换句话说,您正在调用apply对象中的方法Listapply方法的返回类型是特征 List,因此val list的类型是特征List

这意味着当您拨打list.sum时,您正试图调用特征 sum的{​​{1}}方法。但是您的特征List没有List方法,因此失败。

您已将sum方法放在特征sum的伴随对象中 - 您应该将其放入特征中(删除参数;或者调用List中的sum 1}} object,传递List作为参数,正如Seth Tisue在他的评论中所说的那样。)

特征或类不会自动拥有其伴随对象的所有方法。

答案 1 :(得分:0)

回答有关如何实现list.sum的问题:您应该在List trait中定义方法。看看scala.collection.TraversableOnce'sum'实现:

await asyncGenerator(fileList.result.nextPageToken);

到目前为止,List有任意类型,需要Numeric monoid的隐式实例 - 它给出零值和操作(加上sum的情况)