2016-08-21 173 views
3

我最近開始閱讀Paul Chiusano和RúnarBjarnason編寫的Scala中的函數式編程,作爲學習FP的一種手段。我想學習它,因爲它會打開我的頭,扭曲我的思維方式,並希望使我成爲一個更好的程序員整體,或所以我希望。Scala的函數式編程練習

在他們的書中, 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: _*)) 
} 

我現在正在實施的尾法,這應同樣工作在斯卡拉庫中定義的尾巴方法。我想這裏的想法是在List對象中定義一個尾部方法,他們稱之爲伴隨方法,然後在另一個文件(如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)) 

我的問題是:

我這是寫作尾巴方法的正確方法,可能是作者的意圖?這個包裝結構是否正確?因爲我感覺非常錯誤,儘管我只是跟着作者包。

我也不知道我是否應該使用一個特定的類型,而不是寫一個多態的方法(這是什麼名字?)...

多多包涵,因爲我的技術新手的FP。

+0

對我來說這似乎很完美。 雖然: 1.你不想在密封的特質之外顯示出缺點,所以最好把它變成私人的 2.你爲什麼在你的主要功能中需要示例和總變量? – mavarazy

+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對象中。

-1

看起來沒問題。關於什麼?

def tail[A](xs: List[A]): List[A] = xs match { 
    case Nil => Nil 
    case head :: xxs => xxs 
}