函数式编程标量

Functional Programming scala

我从 c​​oursera 关注 "Functional Programming Principles in Scala",第二周的作业大约是 "Purely Functional Sets" 我们有,

type Set = Int => Boolean

然后是一些函数,例如

def union(s: Set, t: Set): Set = (element: Int) => s(element) || t(element)

所以,当我这样做时,

val u = union(Set(1, 2, 3), Set(4, 5, 6))

在 Scala 控制台中,它给出

u: Set = <\function1\>

a) 为什么它是 return 函数?

b) 当我做 contains(u, 6) 它 return 是真的但是我可以显示所有元素吗u 还是因为 u 是一个函数我不能?

c) union(Set(1, 2, 3), Set(4, 5, 6)) return 这两个集合中的所有元素如何没有任何迭代?

a) why is it returning a function?

因为Set是一个函数。 Int => Boolean 表示 "a function taking an Int and returning a Boolean."

b) when I do contains(u,6) it returns true but can I display all elements in u or because u is a function I cannot?

您无法显示所有元素,因为 Set 实际上不是 "contain" 元素。 Set 是一项或多项测试的函数 returning true/false.

c) How does union(Set(1,2,3),Set(4,5,6)) return all elements in those two sets without any iteration?

从给定的 Set 中知道哪些值 return 为真的唯一方法是传入所有可能的值(或一些可接受的近似值)。 Set 中的值将 return true 否则你会得到 false.

注意:这仅适用于问题中定义的 Set。 Scala 标准库中的 Set 是另一种动物。

毫无疑问,这是一项复杂的工作。让我们看看进展如何。
现在我这样做了:

  type Sett = Int => Boolean

  def union(s: Sett, t: Sett): Sett = 
    (element: Int) => s(element) || t(element)

  val x = Set(1, 2, 3).asInstanceOf[Sett]
  val y = Set(4, 5, 6).asInstanceOf[Sett]
  val u = union(x, y)

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

  println(contains(u, 6))

注意我正在使用 Sett!未设置。上面的Set其实就是scala.collections.immutable.Set。 Sett 是我自己的习惯 'type'。该类型定义为 Int => Boolean,即以 Int 为参数且 returns 为布尔值的函数类型。我将自定义类型重命名为 Sett,以避免混淆一个是我的类型,另一个属于 Scala 库。
我在上面的代码中强调的另一件事是,我正在将 Scala 的 Set 转换为我的 Sett!这个演员有效!它是如何工作的?这是因为不可变 Set 继承自 Function1.. 所以效果很好.. 此评论感谢下面的 Jorge
Scala Set 实际上是 Set[Int],因为它是 Set(1,2,3) 等。所以将它转换为合法符合 Int => Boolean 的子类 Sett 是完全合法的。就这样

val x = Set(1,2,3)
println(x(2))
println(x(4))

所以它证明了 Scala 的 Set 在签名上与 Sett 对于这一操作是兼容的。
不需要联合迭代。 Sett 类型持有对两个集合的引用。 如果你这样做:

  def union(s: Sett, t: Sett): Sett =
    (element: Int) => {
      println(element)
      s(element) || t(element)
    }

val u=union(Set(1,2,3),Set(4,5,6)) 

.. 然后你调用 u(2) 或其他什么,union def 被调用时参数 element=2。然后 "s(element) || t(element)" 被调用。集合操作是 1 阶的,即恒定时间。 s(element) 操作不需要迭代,因为 Sets 基本上是 Maps,没有使用 value 部分。只使用 key,key 是唯一的。
马丁·奥德斯基 (Martin Odersky) 真的在这里跳了枪,走得太远了。应该更慢。涵盖的概念太多。