0

我已将以下代码放入 Eclipse 中的 object.Scala 文件中,并且只是想知道“x”的值是什么(应该是 3)。如果我将值放在 List 对象之外的任何位置,则代码将无法编译;同时,在 List 对象中,运行文件不会产生任何输出。

package work

object Work extends App {
  // These 3 lines define a simplified List type
  sealed trait List[+A]
  case object Nil extends List[Nothing]
  case class Cons[+A](head: A, tail: List[A]) extends List[A]

  // This companion object contains basic operations for the List type
  object List {
    def sum(ints: List[Int]): Int = ints match {
      case Nil => 0
      case Cons(x,xs) => x + sum(xs)
    }

    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] =
      if (as.isEmpty) Nil
      else Cons(as.head, apply(as.tail: _*))

    // The next line is the value that I want to return. 
    val x = List(1,2,3,4,5) match {
      case Cons(x, Cons(2, Cons(4, _))) => x
      case Nil => 42
      case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y 
      case Cons(h, t) => h + sum(t)
      case _ => 101
     }

  }
}

我最初将所有内容都放入其中object Work extends App以便编译,否则编译器会抱怨我缺少 Main 方法。但是,为了返回“x”,我尝试放弃 Work 对象,而是将 Main 方法添加到我想要查看的表达式中,如下所示:

def main(args: Array[String]) {
      val x = List(1,2,3,4,5) match {
        case Cons(x, Cons(2, Cons(4, _))) => x
        case Nil => 42
        case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y case Cons(h, t) => h + sum(t)
        case _ => 101
      }
}

但是,然后我收到以下错误:

List 有一个参数类型为 Array[String] 的 main 方法,但 work.List 不是可运行的程序。原因:companion 是一个 trait,这意味着无法生成静态转发器。

我不太确定这意味着什么。我也很困惑如何正确实现 Main 方法。我尝试直接在List对象下添加一个Main方法,封装了List的所有定义和val x,结果比上面的错误还多。我很困惑,仍在网上寻找答案,但到目前为止似乎没有什么能解决我的特定问题。

任何帮助将不胜感激。

以下是我的原始帖子,其中包含更多信息,包括我正在进行的练习的文本。要进行练习,我需要了解表达式的计算方式。正是出于这个原因,我通常在 Scala 工作表中工作,因为我可以在几秒钟内看到我的结果,但是这个特殊的练习涉及使用 trait 和伴随对象,它们的添加对我来说非常复杂,因为我理解它们是如何的在代码中使用,我不知道如何正确实现它们。


原帖


我将以下代码放入 Eclipse IDE 的 Scala Worksheet 中,然后花了大约两个小时尝试不同的方法来制作它

  1. 编译没有错误,并且
  2. 在右侧显示评估结果。

我仍然在(2)中苦苦挣扎。

package fpinscala.datastructures
// The following three lines define a simplified List type and behavior
sealed trait List[+A] 
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]

// The companion object List defines basic List operations
object List { 
  def sum(ints: List[Int]): Int = ints match {
    case Nil => 0 
    case Cons(x,xs) => x + sum(xs) 
  }

  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] = 
    if (as.isEmpty) Nil
    else Cons(as.head, apply(as.tail: _*))
}

当我运行上面的代码时,它会输出一个标准错误,指出缺少主要参数。虽然我不太清楚它是如何工作的def main(args: Array[String) {}object some_object extends App {}但我知道它们允许代码实际编译和运行。同时,过去 Scala 工作表从未要求我有 Main 方法,尽管过去我也没有在同一个文件中使用类或特征。我知道我一定错过了什么。

我试过了

  • 用 App 扩展 List 对象
    • 或者在它下面添加一个 def main 参数
  • 为密封特性创建一个名为“类”的对象,并向其添加主要参数
    • 或使用 App 扩展它
  • 创建一个更大的对象“工作表”,然后我将以下所有内容添加到 def main 参数下
    • 或使用 App 扩展“工作表”
  • 在另一个 Eclipse IDE 文件中,创建一个 New Scala Trait,在其中添加 trait 和类代码,然后尝试将其导入到工作表中,意识到伴随对象 List 需要存在于同一个文件中
  • 将上述所有代码放入一个不同的文件中,尝试将该文件导入工作表,并尝试使任何列表操作工作(这里的问题是我实际上不知道 Eclipse IDE 中哪种类型的 Scala 文件下面的代码将属于对象、类或特征

其中一些已经编译,其他没有,但到目前为止,它们都没有导致工作表在右侧产生实际的评估结果。

这是我一直在尝试的需要上面代码的练习,如果我能真正看到我的代码是如何评估的:

让我们尝试实现几个不同的函数来以不同的方式修改列表。您可以将它和我们编写的其他函数放在 List 伴随对象中。

3.2 实现函数tail,用于删除List的第一个元素。请注意,该函数需要恒定的时间。如果 List 为 Nil,您可以在实现中做出哪些不同的选择?我们将在下一章回到这个问题。

来自Scala 中的函数式编程

非常感谢您的宝贵时间。

4

1 回答 1

2

我不确定您为什么提到将val xList 对象放在外部会阻止您进行编译。

以下编译并产生预期的输出 = 3

object Work extends App {
  // These 3 lines define a simplified List type
  sealed trait List[+A]
  case object Nil extends List[Nothing]
  case class Cons[+A](head: A, tail: List[A]) extends List[A]

  // This companion object contains basic operations for the List type
  object List {
    def sum(ints: List[Int]): Int = ints match {
      case Nil => 0
      case Cons(x,xs) => x + sum(xs)
    }

    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] =
      if (as.isEmpty) Nil
      else Cons(as.head, apply(as.tail: _*))
  }

  // The next line is the value that I want to return.
  val x = List(1,2,3,4,5) match {
    case Cons(x, Cons(2, Cons(4, _))) => x
    case Nil => 42
    case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y
    case Cons(h, t) => h + List.sum(t)
    case _ => 101
  }

  println(x)
}
于 2015-05-10T15:39:40.583 回答