Coursera公开课Functional Programming Principles in Scala习题解答:Week 2

引言

OK.时间很是快又过去了一周。第一周有五一假期因此感受时间绰绰有余,这周中间没有假期仅仅能靠晚上加周末的时间来消化,事实上仍是有点紧张呢!java

后来发现每堂课的视频还有相应的课件(Slide)、字幕(subtitles)可以下载。这样下载视频学习和在线学习就仅仅差课程中间的Exercise了编程

Week 2主要讲函数,函数在Scala里是first-class citizen,可以在随意域内出现。这门课事实上也是在借Scala来说函数式编程原理。框架

好了,很少说。进入习题解析。ide

 

这周的做业主要是使用函数来表示一个集合,可以经过传递给函数一个整型值获得布尔值来验证此整型值是否属于此集合。好,说太绕了,如下是给出的一个栗子:函数式编程

(x: Int) => x < 0


这是一个匿名函数,将一个传入的x映射为布尔值,从而推断x是否属于这个函数表示的集合。很是明显。这个集合是负整数集。函数

题目就从这里開始,使用一个Int到Boolean的函数做为集合的表示,并给其赋了一个别名:post

type Set = Int => Boolean


因此。在本此做业中定义的集合要以函数的形式给出。前面说到的函数是一等公民,固然可以做为返回值。相应的,推断一个值是否在给定集合内的方法例如如下:学习

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


可以看出contains函数传进一个Set和一个Int做为參数,前面提到Set是一个输入为Int类型的函数,因此将s应用到elem上,就获得一个Boolean类型的返回值。ui

 

Exercise 2.1 Basic Functions On Sets

练习2.1完毕集合的一些简单操做的定义。.net

singletonSet

開始固然是定义一个集合啦~这个集合是个单例集合,其仅仅能存放一个值,签名例如如下:

def singletonSet(elem: Int): Set

 

可以使用Int类型的參数来初始化这个函数,返回的是一个Set类型,也就是Int => Boolean的函数。咱们已经知道集合中仅仅包括elem这个元素,那么仅仅需要推断一个元素是否等于elem就可以了。

代码本身写吧……

union, intersect and diff

上面咱们定义了一个最简单的集合,接下来可以经过简单集合的不断组合生成新的集合。

比較常用的三种操做是union、intersect和diff,其原型例如如下:

def union(s: Set, t: Set): Set
def intersect(s: Set, t: Set): Set
def diff(s: Set, t: Set): Set

以上三个操做均是经过组合两个Set获得一个新的Set。分别表示两个集合的并集、交集和差集,这些概念都比較简单。

1.union就是在s中或者在t中的元素组成的集合。因此仅仅需要推断一个元素是否在这二者其一就能够

2.intersect就是在s中且在t中的元素组成的集合,因此需要推断一个元素是否同一时候在这二者中

3.diff就是在s中且不在t中的元素组成的集合,需要推断一个元素在s且不在t中

 

代码。本身写。

filter

接下来是要实现一个filter函数,即选取集合s中符合断言p的元素。这些元素组成的相同是一个集合。filter的原型例如如下:

def filter(s: Set, p: Int => Boolean): Set

这个事实上比較简单了。实质上是intersect的变形,仅仅只是intersect的第二个入參是filter第二个入參的别名罢了。

 

Exercise 2.2 Queries and Transformations on Sets

做业2.2是完毕一些在Set上的操做。

forall

第一个函数给定一个断言,推断Set中的所有元素是否都知足这个断言。签名例如如下:

def forall(s: Set, p: Int => Boolean): Boolean

咱们定义Set的方式决定了没法实际列举Set内的所有元素,仅仅能推断给定元素是否属于这个Set,因此假设要完毕这个功能。咱们需要遍历所有的整型数。

这是不现实的,因此将其限定在-1000到1000范围内。

对于以上的forall函数,题目给出了一个框架,仅仅需要在框架内把对应的部分(即???

部分)填写完成就能够:

def forall(s: Set, p: Int => Boolean): Boolean = {
 def iter(a: Int): Boolean = {
   if (???

) ??? else if (???) ?

?

?

else iter(???

) } iter(???)

}


可以看到forall内部定义了一个函数iter,并将一个iter的实例做为forall的返回值(注意,这里又强调了一次函数是一等公民的概念。)

那么依据上述提示,咱们需要遍历-1000到1000内的整型,依次推断其是否符合断言p,固然前提条件是这个整型也属于集合s。p是一个Int映射到Boolean类型的函数。仅仅需要将整型数传递给它。推断其返回值就能够知道此整型数是否符合p。

推断一个数是否属于集合s可以使用Exercise 2.1中定义的contains函数来实现。

Main.scala中还定义了一个上界:

  /**
   * The bounds for `forall` and `exists` are +/- 1000.
   */
  val bound = 1000


事实上这个仍是比較简单,仅仅需要从-1000到1000。依次推断当中属于集合s的元素是否都符合断言p就能够。假设有一个不符合上述条件。那么返回false;假设都符合,返回true。

请自行实现。

exists

第二个需要实现的函数为exists。即推断集合s中是否含有符合给定断言的元素,签名例如如下:

def exists(s: Set, p: Int => Boolean): Boolean


注意,题目要求exists需要经过调用forall来实现。这个场景好熟悉啊……这不就是高中课本里的题目:“抛N枚硬币所有面都朝上的几率”。和“抛N枚硬币有一次面朝下的几率”之间的关系是同样的么?

OK。分析一下。

推断集合s中是否有符合给定断言的元素,即推断集合s中所有元素是否都不符合给定断言。

假设s中所有元素都不符合给定断言,那么返回false;不然返回true。

懂了吧?下一题。

map

最后一道题目是写一个map函数,将给定集合映射到另一个集合。签名例如如下:

def map(s: Set, f: Int => Int): Set

当中第二个參数f是用来将原集合的元素映射到新集合的函数(一等公民。)

题目看起来简单。仅仅是推断s中的元素通过f映射后。是否有和输入整型相等的就能够。

这当中包括两个步骤:

1.s中是否有符合某个特定条件(断言)的元素

2.特定条件(断言)为通过f映射。等于输入參数

记得返回类型为Set,即Int => Boolean类型的函数(一等公民!)!

 

结语

总体来讲,Scala有别于其它面向对象语言的一个最大的特色是其混合了很是多函数式编程的概念和方法,这在使用Scala的过程当中尤为要注意!Scala可以看作是O教(面向对象编程)和F教(函数式编程)的合体。

PS:这次附带的FunSetSuite.scala中仅仅有很是少一部分測试用例,另外一些是被打上了ignore标签,假设本身有兴趣,能够试着写一些单元測试,保证能够覆盖到一些特殊状况,这样就不至于重复在Coursera的server上提交不完美的答案了!

PPS:现在补上了做业题目的下载连接和题面(防止网页失效带来的不便。以离线网页的形式给出),方面之后看到的同窗本身练习。

第二章题目下载地址:http://download.csdn.net/detail/doggie_wangtao/7343177

Coursera公开课Functional Programming Principles in Scala习题解答:Week 1 

声明:

本文为原创,禁止用于不论什么商业用途。转载请注明出处:http://blog.csdn.net/asongoficeandfire/article/details/25661661

相关文章
相关标签/搜索