我只是想了解下面的代码:
这里声明了一个新类型别名Set,它是一个接受Int的函数 参数并返回一个布尔值
type Set = Int => Boolean
这里声明了一个新方法'contains',它接受Set和Int类型的两个参数 返回一个布尔值。布尔值设置为前面声明的函数 ('type Set = Int => Boolean') 但是执行什么逻辑来确定Int'elem'是否是Set's'
的成员def contains(set: Set, elem: Int): Boolean = set(elem)
这里定义了一个方法,它返回一个返回函数的集合?
def singletonSet(elem: Int): Set = set => set == elem
包含评论的完整代码:
/**
* We represent a set by its characteristic function, i.e.
* its `contains` predicate.
*/
type Set = Int => Boolean
/**
* Indicates whether a set contains a given element.
*/
def contains(set: Set, elem: Int): Boolean = set(elem)
/**
* Returns the set of the one given element.
*/
def singletonSet(elem: Int): Set = set => set == elem
答案 0 :(得分:88)
让我们按逻辑顺序向后阅读。
假设你有一组有限的整数:例如0, 1, 2, 3, 5, 8
描述这组整数的一种方法是通过一个函数(characteristic or indicator function),对于每个整数,如果整数在集合中,则返回true,否则返回false。
正如我们所描述的,这个函数的签名必须始终是Int => Bool
(“给我一个整数,我会告诉你它是否在集合中”),而它的实现将根据具体的集合而变化。 / p>
对于上面示例中的设置,您可以将此函数简单地写为:
val mySet: Int => Boolean = x => Array(0,1,2,3,5,8) contains x
或者认识到集合中的int是Fibonacci序列的第一个,并以稍微复杂的方式定义f(我不会在这里做...)。 请注意,我使用的“包含”是为所有scala集合定义的。 在任何情况下,现在你都有一个函数可以告诉你集合中的内容和不集合的内容。 我们在REPL中尝试一下。
scala> val mySet: Int => Boolean = x => Array(0,1,2,3,5,8) contains x
mySet: Int => Boolean = <function1>
scala> mySet(3)
res0: Boolean = true
scala> mySet(9)
res1: Boolean = false
现在,mySet的类型为Int => Boolean
,如果我们将其定义为类型别名,我们可以使其更具可读性。
scala> type Set = Int => Boolean
defined type alias Set
除了可读性之外,将Set
定义为Int => Boolean
的别名是明确表示Set 是的特征函数。我们可以使用Set
类型别名以更简洁(但在其他方面等效)的方式重新定义mySet:
scala> val mySet: Set = x => Array(0,1,2,3,5,8) contains x
mySet: Int => Boolean = <function1>
现在是这个长答案的最后一部分。让我们定义一个特征函数来描述这个Singleton集:3
。
易:
val Singleton3 : Set = set => set == 3
对于仅包含4的Singleton集合,它将是:
val Singleton4 : Set = set => set == 4
因此,让我们概括一下这些函数的创建,并编写一个返回Singleton函数的方法,对于任何整数,该函数描述仅包含该整数的集合:
def singletonSet(elem: Int): Set = set => set == elem
<强>附录强>
我跳过了这一部分,因为它并不是真的需要:def contains(set: Set, elem: Int): Boolean = set(elem)
我认为这有点毫无意义,并且(没有更多上下文)它看起来就像一个人为的例子来演示如何将函数作为参数传递,就像scala中的任何其他类型一样。需要Int => Bool
函数和Int
才能将函数应用于Int
,以便您可以执行
scala> contains(mySet, 3)
res2: Boolean = true
就像直接调用mySet(3)
一样。
答案 1 :(得分:4)
在观看关于“Currying”的讲座视频后,我相信Paolo的解决方案表达方式更为简洁:
def singletonSet(elem: Int): Set = {
def innerFunction (givenElement: Int) =
if (elem == givenElement) true
else false
innerFunction
}
如果我错了,Plesae纠正我!
答案 2 :(得分:1)
回答你的问题 - 但是执行了什么逻辑来确定Int'elem'是否是Set's'的成员
执行实际函数调用时会执行此操作。请考虑以下函数调用。
包含(singletonSet(1),1)
现在,singletonSet被定义为 def singletonSet(elem:Int):Set = x =&gt; x == elem (为了清楚起见,我选择使用标识符x)。 singletonSet的返回类型是Set类型的函数,它接受Int参数并返回Boolean。所以上面的调用函数的第一个参数singletonSet(1)等于函数 x =&gt; x == 1 因为这里的元素是1.所以我们得到
包含((x =&gt; x == 1),1)
现在考虑包含函数的定义 def contains(f:Set,elem:Int):Boolean = f(elem)。上面调用中的第一个参数是函数x =&gt; x == 1代替形式参数f,第二个参数1代替形式参数elem。 contains的返回值是函数f(elem),它等于f(1)。由于f(x)定义为(x == 1),f(1)等于(1 == 1),返回true。
按照相同的逻辑,像contains(singletonSet(1),2)这样的函数调用最终会等同于(1 == 2),它将返回false。
答案 3 :(得分:1)
我现在正在上课,也很困惑,但我想我现在明白了。
def singletonSet(elem: Int): Set = (x : Int) => x == elem
这里singletonSet是一个函数,它返回一个类型为Set 的函数,定义为type Set = Int => Boolean
所以当你调用def contains(s:Set, elem:Int): Boolean = s(elem)
时,例如:contains(singletonSet(1), 2)
,singletonSet(1)返回一个函数,其中elem(在singletonSet的定义中)设置为1,而2(也定义为elem,但是在contains的参数中定义)作为x在singletonSet定义中传入,我们需要摆脱java set的想法,我们不需要singletonSet来保持我们设置的值。
为了更好地理解,我们可以更改参数名称,如下所示:
def singletonSet(elemToStore: Int): Set = (x : Int) => x == elemToStore
def contains(s: Set, elemToCheck: Int): Boolean = s(elemToCheck)