2012-10-24 84 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)