Scala过滤别名集的所有元素
Posted
技术标签:
【中文标题】Scala过滤别名集的所有元素【英文标题】:Scala filter on all elements of an alias Set 【发布时间】:2018-03-17 19:24:16 【问题描述】:这是问题。
我有这个类型集:
type Set = Int => Boolean
我可以这样使用:
val belowNegFive: Set = (i) => i < -5
belowNegFive(10)
我的意思是返回一个布尔值,具体取决于元素 10 是否属于 -5 以下的数字集。
-
我有这段代码,它返回
s
的子集,p
持有该子集。
def filter(s: Set, p: Int => Boolean): Set = (e: Int) => s(e) && p(e)
Q1:我怎么知道 p(e) 告诉我 int e 满足谓词 p?
-
我有这个 fc,它返回
s
内的所有有界整数是否满足 p
。
def contains(s: Set, elem: Int): Boolean = s(elem) val bound = 1000 def forall(s: Set, p: Int => Boolean): Boolean = def iter(a: Int): Boolean = if (a > bound) true else if (contains(s, a) && !p(a)) false else iter(a+1) iter(-bound)
Q2:为什么所有的 a > 边界默认都简单地满足谓词的条件?或者 true 只是一个停止条件?我不确定为什么这个 fc 不返回无限循环。只是一个无限的布尔值列表,最后一个布尔值对于所有 a > 边界都是“真、真、真……”。
Q3:我看不出它在哪个点使用 && 在结果布尔值之间表示是,s
内的所有有界整数都满足 p
。
谢谢
【问题讨论】:
第一部分没看懂。您能否详细说明您想在第一季度提出的问题?p
是 Int=>Boolean
和 e
是 Int
因此 p(e)
是 Boolean
。所以e
满足p
如果p(e)
返回true
。
我可能回答了你自己的问题。我注意到谓词 p: Int => Boolean 的处理方式与类型 Set = Int => Boolean 相同。如果我们将 s 定义为 Set,则方法 s(e: Int) 指示 e 是否属于 Set s。所以 p(e: Int) 应该有相同的结果。
如果 a > bound
则您已经遍历了 a
的所有可能值(在边界内)。如果您现在还没有找到false
,那么就没有。如果没有false
,那么它必须是true
。
如果s
确实not 包含a
,那么我们不关心谓词p(a)
是否成立。因此,如果a
不是 s
的成员,则将跳过谓词测试。只有当a
是 s
的成员时,我们才会测试谓词p(a)
。
【参考方案1】:
对于第一季度:
p
是一个接受整数并返回布尔值的函数。我的谓词可能类似于,number 应该小于 -10。我的设置可以,应该小于-5。 filter
将返回两者都持有的自定义集。
type Set = Int => Boolean
val belowNegFive: Set = (i) => i < -5
def filter(s: Set, p: Int => Boolean): Set = (e: Int) => s(e) && p(e)
val predicate: Int => Boolean = (num) => num < -10
val myset = filter(belowNegFive, predicate)
myset(0) #=> false
myset(-1) #=> false
myset(-10) #=> false
myset(-11) #=> true
第二季度:
def contains(s: Set, elem: Int): Boolean = s(elem)
val bound = 1000
def forall(s: Set, p: Int => Boolean): Boolean =
def iter(a: Int): Boolean =
if (a > bound) true
else if (contains(s, a) && !p(a)) false
else iter(a+1)
iter(-bound)
这是一个停止条件。 forall
规定,如果对于所有整数 b/w -1000 到 1000(绑定),如果 set 包含整数并且谓词成立,则为真。如您所见,在最后一行中,检查从 -1000 (iter(-bound)
) 开始。
Q3:集合和谓词的真值表是什么样的?
set | predicate | should continue checking?
____________________________________________
true | true | yes
false| true | yes
true | false | no
false| false | yes
如您所见,它应该返回false
的唯一条件是第三个条件,即else if
条件。对于所有其他人,它会继续检查下一个整数是否存在于集合和谓词中。
【讨论】:
你好。 Q1:我明白了。关于它的另一个问题。我有代码: type Set = Int => Boolean def fc(s: Set) = (i: Int) => s(i) 编译器如何知道 s(i) 是谁?我没有定义它。我只有这 2 行代码。 对于 Q2、Q3:我仍然不确定停止条件。我了解真值表。但是 fc "iter" 接收 -100 到 100 之间的所有数字作为输入(-bound 和 bound)。所以一个整数列表。但它只返回一个布尔值。对我来说,我认为它返回由 if 条件产生的最后一个布尔值。 (“Iter”是一个递归 fc。但是使用其他递归 fc(例如阶乘)要容易得多。从代码中可以明显看出,所有先前的结果都相互相乘,直到达到停止条件 n == 1。这里, 停止条件为 > 界限并不明显。) 我看到数字a可以继续增加到101、102...(为什么不呢?)。在这种情况下,“a > bound”会给出无限的真布尔值(也许我错过了这些递归 fc 背后的一般原则)a > bound
只是这个函数中的一个停止条件,就像在阶乘函数中你在 n == 1 处停止一样。我认为你也可以用 a == bound + 1
代替 a > bound
这将消除与无限集的一些混淆。我同意这不是最好的迭代函数。其他递归函数的代码有不同的目标,它们将最后的结果带入新的值,它们遵循尾递归。这只是一个没有 for/while 循环的迭代。
对于def fc(s: Set) = (i: Int) => s(i)
。 s
是一个 Set
,这里定义为一个接受整数并返回布尔值的函数。在这种情况下,s(i) 自然知道它的返回类型为布尔值。以上是关于Scala过滤别名集的所有元素的主要内容,如果未能解决你的问题,请参考以下文章