【发布时间】:2016-08-21 10:52:32
【问题描述】:
我最近开始阅读 Paul Chiusano 和 Rúnar Bjarnason 撰写的Scala 中的函数式编程一书,作为学习 FP 的一种方式。我想学习它,因为它会打开我的脑袋,改变我的思维方式,并希望让我成为一个整体上更好的程序员,或者我希望如此。
在他们的书中,Chp。 3,他们定义了一个基本的单链表类型如下:
package fpinscala.datastructures
sealed trait List[+A]
case object Nil extends List[Nothing]
case class Cons[+A](head: A, tail: List[A]) extends List[A]
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: _*))
}
我现在正致力于实现 tail 方法,它的工作方式类似于 Scala 库中定义的 tail 方法。我猜这里的想法是在 List 对象中定义一个 tail 方法,他们称之为 companion 方法,然后在另一个文件(如 Main 文件)中正常调用它。
到目前为止,我有这个:
def tail[A](ls: List[A]): List[A] = ls match {
case Nil => Nil
case Cons(x,xs) => xs
}
然后我在另一个文件夹中创建了一个主文件:
package fpinscala.datastructures
object Main {
def main(args:Array[String]):Unit = {
println("Hello, Scala !! ")
val example = Cons(1, Cons(2, Cons(3, Nil)))
val example2 = List(1,2,3)
val example3 = Nil
val total = List.tail(example)
val total2 = List.tail(example3)
println(total2)
}
}
这有效并给了我:
Hello, Scala !!
Cons(2,Cons(3,Nil))
我的问题是:
这是否是编写 tail 方法的正确方法,可能如作者所愿?这个包结构是否正确?因为我觉得很不对劲,虽然我只是跟着作者的包走。
我也不知道我是否应该使用特定类型而不是编写多态方法(这是名字吗?)...
请耐心等待,因为我是 FP 艺术的新手。
【问题讨论】:
-
这对我来说似乎非常好。虽然:1.您不想在密封特征之外显示 Cons,所以最好将其设为私有 2.为什么在主函数中需要示例和总变量?
-
谢谢!我如何“封装”缺点以使其私有?我理解这个例子,但是改变实际的类对我来说还是有点太多了,而且在书中他们要求添加简单的方法,比如 tail 等等......所以我很茫然。关于例子,好吧,我想测试一下?
标签: scala functional-programming