Scala设置功能

时间:2011-08-05 23:52:43

标签: scala functional-programming set

在Stanford Scala课程中,我遇到了以下任务:

练习1 - 设置为函数:

在本练习中,我们将集合表示为从Ints到Booleans的函数:

type Set = Int => Boolean

a )编写一个函数“set”,它接受一个I​​nt参数并返回一个包含该Int的集合。

b )编写一个函数“contains”,它将Set和Int作为参数,如果Int在Set中则返回true,否则返回false。

c )编写函数“union”,“intersect”和“minus”,它们将两个Set作为参数并返回一个Set。

d )你能编写一个函数“subset”,它将两个Sets作为参数,如果第一个是第二个的子集则返回true,否则返回false?

a b c 的解决方案相当简单:

def set(i: Int): Set = n => n == i

def contains(s: Set, i: Int) = s(i)

def union(a: Set, b: Set): Set = i => a(i) || b(i)

def intersect(a: Set, b: Set): Set = i => a(i) && b(i)

def minus(a: Set, b: Set): Set = i => a(i) && !b(i)

d 有没有优雅的解决方案? 当然,严格地说, d 的答案是“是”,因为我可以这样写:

def subset(a: Set, b: Set) = Int.MinValue to Int.MaxValue filter(a) forall(b)

但这可能不是正确的方法。

6 个答案:

答案 0 :(得分:9)

如果不迭代所有整数,我认为这是不可能的。对于伪证明,请查看所需的类型:

def subset: (a: Set, b: Set): Boolean

不知何故,当我们需要处理的是Boolean类型的集合(ab)和整数相等时,我们必须生成Int => Boolean (Int, Int) => Boolean。从这些原语中,获取Boolean值的唯一方法是从Int值开始。由于我们手中没有任何特定的Int,唯一的选择是迭代所有这些。

如果我们有一个神奇的神谕isEmpty: Set => Boolean,那么故事会有所不同。

最后一个选项是将编码“false”作为空集,将“true”作为其他任何内容,从而将所需类型更改为:

def subset: (a: Set, b: Set): Set

使用此编码,逻辑“或”对应于集合并联操作,但我不知道可以轻松定义逻辑“和”或“不”。

答案 1 :(得分:1)

我们有

Set A = 
    Returns the intersection of the two given sets,
    the set of all elements that are both in `s` and `t`.

Set B = 
    Returns the subset of `s` for which `p` holds.

不是Set A等同于Set B

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

答案 2 :(得分:0)

我同意Kipton Barros,你必须检查Ints的所有值,因为你要证明forall x, a(x) implies b(x)

关于它的优化,我可能会写:

  def subset(a: Set, b: Set) = Int.MinValue to Int.MaxValue exists(i => !a(i) || b(i))

因为!a(i) || b(i)相当于a(i) implies b(i)

答案 3 :(得分:0)

稍后在Coursera练习中引入有界集,然后将forall()和exists()作为范围内的通用和存在量词。 subset()不在练习中,但与forall相似。这是我的子集()版本:

// subset(s,p) tests if p is a subset of p returning true or false
def subset(s: Set, p: Set): Boolean = {
  def iter(a: Int): Boolean = {
    if (a > bound) { true
    } else if (contains(p, a)) {
        if (contains(s, a)) iter(a + 1) else false
    } else iter(a+1)
  }
  iter(-bound)
}

答案 4 :(得分:0)

以下是使用contains函数的另一个版本:

def union(s: Set, t: Set): Set = x => contains(s,x) || contains(t,x)

def intersect(s: Set, t: Set): Set = x => contains(s,x) && contains(t,x)

def diff(s: Set, t: Set): Set = x => contains(s,x) && !contains(t,x)

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

答案 5 :(得分:-1)

如果有两个集合A和B,则A相交B是A和B的子集。数学证明:A ∩ B ⊆ A and A ∩ B ⊆ B。功能可以这样写:

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

def intersect(s: Set, t: Set): Set = x => s(x) && t(x)
def filter(s: Set, p: Int => Boolean): Set = intersect(s,p)