在Stanford Scala课程中,我遇到了以下任务:
练习1 - 设置为函数:
在本练习中,我们将集合表示为从Ints到Booleans的函数:
type Set = Int => Boolean
a )编写一个函数“set”,它接受一个Int参数并返回一个包含该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)
但这可能不是正确的方法。
答案 0 :(得分:9)
如果不迭代所有整数,我认为这是不可能的。对于伪证明,请查看所需的类型:
def subset: (a: Set, b: Set): Boolean
不知何故,当我们需要处理的是Boolean
类型的集合(a
,b
)和整数相等时,我们必须生成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)