【问题标题】:scala coursera functional programing assignment FunSetsscala coursera 函数式编程作业 FunSets
【发布时间】:2018-06-05 05:46:03
【问题描述】:

我在 coursera 上的 scala 中参加了 martin odersky 的函数式编程课程。
但是,我无法理解第二个作业 Funsets.scala 的解决方案。

type Set = Int => Boolean

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

  /**
   * Returns the union of the two given sets,
   * the sets of all elements that are in either `s` or `t`.
   */
  def union(s: Set, t: Set): Set = (e: Int) => s(e) || t(e)

问题在上面的函数中,什么是e?它从何而来 ?我知道 union 函数结合了这两个集合,但是这里我从方法定义中理解的是,它需要 2 个集合作为输入并返回结果并集,那么 e 是从哪里来的呢?

  /**
   * Returns the intersection of the two given sets,
   * the set of all elements that are both in `s` or `t`.
   */
  def intersect(s: Set, t: Set): Set = (e: Int) => s(e) && t(e)

同样的问题也适用于相交函数。
请任何人解释一下上述两个函数的操作,即这两个语句

(e: Int) => s(e) || t(e)(e: Int) => s(e) && t(e)

【问题讨论】:

  • Set 一个函数!所以,在intersectreturn 一个函数。它是一个返回函数的函数。一开始可能听起来很吓人,但它非常强大。与传递“普通”参数一样,您可以传递一个函数(此处为Set)。就像你说的“如果我有一个Int 类型的e,那么intersect 将返回......”

标签: scala functional-programming purely-functional


【解决方案1】:

e 称为参数。当函数应用于参数时,参数会绑定到 参数

例如在函数中

val f: Int ⇒ Int = i ⇒ i + 1

i 是一个参数。如果如果将f 引用的函数应用到一个参数,比如2,那么在函数内部,i 绑定到参数的值,即在函数内部,取消引用i 的计算结果为@987654328 @。因此,应用f 引用的函数将评估为3

f(2)
//=> 3

【讨论】:

  • 感谢您的回答。我习惯于编写命令式 Java 代码和函数式编程的新手,因此很难消化您提供的解释。我将函数分解为多个部分:- def union(s: Set, t: Set): Set = (e: Int) => s(e) || t(e) => 根据我的理解,当我们应用 union(Set(1,2),Set(2)) 之类的联合函数时,在内部,'e' 是指向集合中每个元素的指针。请让我知道是否有任何我需要首先学习的函数式编程概念才能理解这一点。谢谢。
  • 不,e 不是指针。它是函数的参数。函数可以有参数。参数有点像函数定义中的“洞”,我们可以在每次应用函数时填充不同的值(称为“参数”)。它与方法完全相同。在方法def inc(i: Int) = i + 1中,有一个参数i,当我们调用inc(2)这样的方法时,我们将值2作为参数绑定到参数i,结果为3 .
  • 在函数val inc: Int ⇒ Int = i ⇒ i + 1中,有一个参数i,当我们将函数应用到像inc(2)这样的参数时,我们将值2作为参数绑定到参数i,结果为3
  • 是的,但我们没有在 union 或 intersect 定义的函数定义中的任何地方写上 'e'。那么它是如何与函数绑定的呢?
  • 我不明白你的问题。首先,unionintersect 是方法,而不是函数,因此它们没有具有“函数定义”。其次,为什么e 会被声明为unionintersect 的参数?它是由unionintersect 返回 的函数的参数。最后,e 在由intersectunion 返回的函数的参数列表中声明,例如这里:(e: Int) => s(e) || t(e) 在这个函数文字中,e 被声明为唯一的参数,并声明为 Int 类型。
【解决方案2】:
def union(s: Set, t: Set): Set = (e: Int) => s(e) || t(e)

让我们把它分解成小块。

  • def union() 我正在定义一个方法,我将调用 union
  • (s: Set, t: Set) 此方法将采用两个参数,我将调用它们 st,它们都是 Set 类型。
  • : Set 此方法将返回类型为Set 的值。等等……Set 是什么?
  • type Set = Int => Boolean 啊,好的,Set 是一个函数,它接受 Int 作为参数并返回 Boolean 作为结果。知道了。回到union() 方法。
  • (e: Int) => s(e) || t(e) 这是一个接受Int 类型的单个参数的函数。我将调用该参数e。当此函数接收到Int 时,它将被同时提供给stst 都是 Set 类型,这意味着当输入 Int 时,它们会返回 Boolean。那么我们将有 2 个 Boolean 值,它们将被或在一起以产生一个 Boolean,它与 Set 的定义相匹配(Int 输入,Boolean 输出),所以我们完成了。

现在让我们创建一个示例,看看如何使用它。

val setA:Set = x => x == 5   //this Set is true only for 5
val setB:Set = y => y == 2   //this Set is true only for 2
val setU = union(setA, setB) //setA is parameter s, setB is parameter t

setU(2)  //'e' is now 2, this returns true
setU(5)  //'e' is now 5, this returns true
setU(25) //'e' is now 25, this returns false

【讨论】:

  • 感谢您的回答。我习惯于编写命令式 Java 代码和函数式编程的新手,因此很难消化您提供的解释。我将函数分解为多个部分:- def union(s: Set, t: Set): Set = (e: Int) => s(e) || t(e) => 根据我的理解,当我们应用 union(Set(1,2),Set(2)) 之类的联合函数时,在内部,'e' 是指向集合中每个元素的指针。请让我知道是否有任何我需要首先学习的函数式编程概念才能理解这一点。谢谢。
  • @ChaitanyaWaikar;您将 Scala 标准库中的集合 Set 与为本练习定义的函数 Set 混淆了。 Set(1,2) 是一个集合,不适合 union() 参数类型。请参阅我添加到答案中的用法示例。而且,不,e 不是指针。它是函数的参数。如果我写setU(7),那么7 将传递给union() 方法创建的函数。 e 被赋值给 7 直到函数返回。
  • 这里描述了一些可能对您有所帮助的概念。想象一个带有 2 个参数的函数。现在只用第一个参数而不是第二个参数调用这个函数。命令式语言不允许这样做。它不会编译。但是函数式语言有一种叫做“currying”的东西,它确实允许这样做。当您仅使用第一个参数调用此函数时,返回的是一个采用第二个参数的新函数。当新函数被正确的参数调用时,原函数的计算就完成了。
  • 现在我明白了。非常感谢。
【解决方案3】:

记住Set 在这个赋值中是如何定义的:它只是一个接受Int 并返回Boolean 的函数。当您将一些Int 传递给此函数时,如果IntSet 中,则该函数返回true,否则返回false。换句话说,这种类型的Set 与其说是真正的集合,不如说是定义在给定的Set 中的含义。

现在,在两个Sets 之间调用union 有什么作用?好吧,它产生了一个Set,其成员至少在这两个Sets 之一中。请记住,Set 只是一个 Int => Boolean 函数,所以:

(e: Int) => s(e) || t(e)

是一个函数,它接受一些Int 参数,将其称为e,如果s(e) 为真或t(e) 为真,则返回真。根据union方法声明,st是什么?

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

s 是描述Int 是否在Set s 中的函数;同样适用于t。因此,s(e) || t(e) 意味着e 必须在一个或两个Sets 中,以便两个Sets 中的union 返回true——这正是union 的定义。

【讨论】:

  • 感谢您的回答。我习惯于编写命令式 Java 代码和函数式编程的新手,因此很难消化您提供的解释。我将函数分解为多个部分:- def union(s: Set, t: Set): Set = (e: Int) => s(e) || t(e) => 根据我的理解,当我们应用 union(Set(1,2),Set(2)) 之类的联合函数时,在内部,'e' 是指向集合中每个元素的指针。请让我知道是否有任何我需要首先学习的函数式编程概念才能理解这一点。谢谢。
【解决方案4】:

正如视频讲座中提到的......我们应该为基函数分配一个匿名函数。

这里,(x: Int) 不是从某个地方带来的,将其视为不同函数的函数参数。 例如:

def num(s: FunSet): FunSet = (x: Int) => x

this is similar to, 
def function(x: Int) = x

def num(s: FunSet): FunSet = function

我希望这对未来的学习者有所帮助......!我也有这个疑问……

【讨论】:

    猜你喜欢
    • 2013-03-31
    • 1970-01-01
    • 2016-05-12
    • 2011-05-07
    • 1970-01-01
    • 2017-04-16
    • 1970-01-01
    • 2018-02-08
    • 2020-07-24
    相关资源
    最近更新 更多