使用Scala进行功能编程练习

时间:2016-08-21 10:52:32

标签: scala functional-programming

我最近开始阅读Paul Chiusano和RúnarBjarnason撰写的“ 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方法,他们称之为伴侣方法,然后在另一个文件(如主文件)中正常调用它。

到目前为止,我有这个:

def tail[A](ls: List[A]): List[A] = ls match {
    case Nil => Nil
    case Cons(x,xs) => xs
    }

然后我在另一个文件夹中创建了一个Main文件:

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))

我的问题是:

这可能是编写尾部方法的正确方法,正如作者所预期的那样吗?这个包装结构是否正确?因为我感觉非常不对,虽然我只是跟着作者的包裹。

我也不知道我是否应该使用特定类型而不是编写多态方法(这是名字吗?)...

请耐心等待我,因为我是FP的新手。

2 个答案:

答案 0 :(得分:2)

在默认的Scala列表实现中,尝试获取空列表的尾部会抛出UnsupportedOperationException。所以你可能想要更像

的东西
def tail[A](ls: List[A]): List[A] = ls match {
    case Nil => throw new UnsupportedOperationException()
    case Cons(x,xs) => xs
}

另外,qantik的回答他建议使用::运算符可以使用Scala的默认列表实现,但由于没有在此自定义列表实现上定义的::方法,因此它不起作用。

最后,您可能需要考虑定义尾部,而不是执行

val list = List(1, 2, 3)
val restOfList = tail(list). 

你可以改为

val list = List(1, 2, 3)
val restOfList = list.tail

这将需要在List trait上定义方法,而不是在List对象中。

答案 1 :(得分:-1)

看起来没问题。怎么样?

<uses-sdk tools:overrideLibrary="the library package name" />

<uses-sdk tools:node="replace" />