2012-10-24 122 views
32

我只是想了解下面的代碼:我對以下scala代碼的理解是否正確?


這裏一個新的類型別名設置聲明這是接受一個int參數 並返回一個布爾

type Set = Int => Boolean 

功能

這裏聲明瞭一個新方法'contains',它帶有兩個參數Set和Int ,它返回一個布爾值。的布爾值被設置爲在早期 (「類型設置= INT =>布爾」) 但是執行什麼邏輯以確定是否INT「ELEM」被設置的'

def contains(set: Set, elem: Int): Boolean = set(elem) 
的成員聲明的函數

這裏定義了一個方法,它返回一個返回函數的集合?

def singletonSet(elem: Int): Set = set => set == elem 

完整的代碼註釋:

/** 
    * We represent a set by its characteristic function, i.e. 
    * its `contains` predicate. 
    */ 
    type Set = Int => Boolean 

     /** 
     * Indicates whether a set contains a given element. 
     */ 
def contains(set: Set, elem: Int): Boolean = set(elem) 

     /** 
     * Returns the set of the one given element. 
     */ 
     def singletonSet(elem: Int): Set = set => set == elem 
+8

你問的答案coursera斯卡拉課程作業2 –

+38

我相信他只是要求解釋。事實上,我現在正在學習這門課,功能編程對我來說是全新的。我也有這個assingment的問題...我不想解決方案 - 只是解釋。下面的保拉給出了我所需要的。 – Moby04

+3

我也直覺如何寫這個(最終),但受益於保羅的答案。不是每個來這裏的人都試圖欺騙。感謝Moby捍衛這個問題如何被問到的細節。 +1 – noogrub

回答

79

讓我們閱讀類的倒退,在邏輯順序。

假設你有一個有限的整數組:0, 1, 2, 3, 5, 8例如

一種方式來描述這個整數集是通過函數(其characteristic or indicator function),對於每一個整數,若整數是在返回true設置,如果不是,則爲false。 正如我們所描述的,這個函數的簽名必須始終爲Int => Bool(「給我一個整數,我會告訴你它是否在集合中)」,而其實現將根據特定集合而變化。

對於我的例子中,設置上面,你可以寫這個功能只是爲:

val mySet: Int => Boolean = x => Array(0,1,2,3,5,8) contains x 

或認識到,在該組中的整數是斐波那契序列的第一批和一個稍微複雜的將f方式(我不會在這裏做...)。 請注意,我使用的「包含」是爲所有scala集合定義的。 無論如何,現在你有一個函數可以告訴你什麼是在集合中,什麼不是。 讓我們在REPL中嘗試它。現在

scala> val mySet: Int => Boolean = x => Array(0,1,2,3,5,8) contains x 
mySet: Int => Boolean = <function1> 

scala> mySet(3) 
res0: Boolean = true 

scala> mySet(9) 
res1: Boolean = false 

,MYSET具有類型Int => Boolean,我們可以讓更多的可讀性,如果我們把它定義爲一個類型別名。

scala> type Set = Int => Boolean 
defined type alias Set 

而且可讀性,定義Set作爲Int => Boolean別名是擺明是在某種程度上一套其特色功能。我們可以在一個更簡潔(但完全等同)的方式與Set類型別名重新定義MYSET:

scala> val mySet: Set = x => Array(0,1,2,3,5,8) contains x 
mySet: Int => Boolean = <function1> 

現在到了最後一塊這麼久的答案。我們來定義一個特徵函數來描述這個單例集:3。 簡單:

val Singleton3 : Set = set => set == 3 

只包含4辛格爾頓集,這將是:

val Singleton4 : Set = set => set == 4 

所以,讓我們概括了這些功能的創作和編寫返回一個Singleton功能的方法,對於任意整數,描述了含有隻整數集合:

def singletonSet(elem: Int): Set = set => set == elem 

附錄:

我跳過這一部分,因爲它是不是真的需要:def contains(set: Set, elem: Int): Boolean = set(elem)

我覺得這有點沒有意義的,(沒有更多的情況下),它看起來就像一個人爲的例子來演示如何可以傳遞一個函數作爲參數,就像scala中的任何其他類型一樣。它採用Int => Bool功能和Int,只是應用功能的Int所以你可以做

scala> contains(mySet, 3) 
res2: Boolean = true 

這就好比直接調用mySet(3)

+2

我同意你的附錄:這基本上是Lambda微積分中的集合的教會編碼(奇怪的還是面向對象的編碼 - 參見[*關於理解數據抽象,重訪*](http:// CS。 UTexas.Edu/~wcook/Drafts/2009/essay.pdf)[William R. Cook](http://WCook.BlogSpot.Com/)來理解爲什麼)。巧妙的是,套件同時是對象和特徵函數,這個「包含」方法不必要地遮蔽了漂亮的設計。 –

+0

@JörgWMittag漂亮的文章,謝謝! –

+0

@PaoloFalabella什麼是「val Singleton4:Set = set => set == 4」的詳細方式我無法理解「set」參數來自哪裏 –

4

觀看「柯里化」的演講視頻後,我相信保羅的解決方案在一個更詳細的方式表達是:

def singletonSet(elem: Int): Set = { 
    def innerFunction (givenElement: Int) = 
     if (elem == givenElement) true 
     else false 
     innerFunction 
    } 

Plesae糾正我,如果我錯了!

+1

使用匿名函數可以縮短很多:'def singletonSet(elem:Int):Set =(x:Int)=> elem == x' –

+0

singletonSet方法返回一個set,其中因爲閉包返回一個布爾值。我很困惑。 –

1

要回答你的問題 - 但執行什麼邏輯,以確定是否INT「ELEM」設置「S」

這是當你實際的函數調用進行的一員。考慮下面的函數調用。

含有(singletonSet(1),1)

現在singletonSet被定義爲DEF singletonSet(ELEM的:int):設定= X => X == ELEM(I選擇使用爲了清楚起見,標識符x)。 singletonSet的返回類型是Set類型的函數,它接受一個I​​nt參數並返回布爾值。所以上面的調用函數的第一個參數singletonSet(1)等同於功能X => X == 1作爲ELEM這裏是1。所以我們得到

包含((X => X == 1) ,1)

現在考慮的定義包含功能DEF含有(F:設置,ELEM的:int):布爾= F(ELEM)。上述調用中的第一個參數是函數x => x == 1,它用形式參數f代替,第二個參數1代替形式參數elem。 contains的返回值是等於f(1)的函數f(elem)。由於f(x)定義爲(x == 1),f(1)等於(1 == 1),它返回true。

通過相同的邏輯,類似contains(singletonSet(1),2)的函數調用最終會等於(1 == 2),它將返回false。

+0

拉姆亞,這將如何工作以下場景?def包含(s:Set,elem:Int):Boolean = s(elem); val set:Set = Set(1,2,3,4); 包含(set,5); 在這種情況下,我創建了一組超過1個值。這工作得很好。它是否迭代所有的值? – Rahul

0

我現在正在接受這個課程,也感到困惑,但我想我現在明白了。

def singletonSet(elem: Int): Set = (x : Int) => x == elem

這裏singletonSet是與該類型設置,其被定義爲type Set = Int => Boolean

返回的功能的功能,以便當調用def contains(s:Set, elem:Int): Boolean = s(elem),例如:contains(singletonSet(1), 2),singletonSet(1)是用elem(在singletonSet的定義中)設置爲1返回一個函數,並且2(也定義爲elem,但是在contains的參數中定義)作爲singletonSet定義中的x傳入,我們需要去掉java設想,我們不需要singletonSet來堅持我們設定的值。

爲了更好地理解,我們可以改變參數名稱如下:

def singletonSet(elemToStore: Int): Set = (x : Int) => x == elemToStore

def contains(s: Set, elemToCheck: Int): Boolean = s(elemToCheck)