斯卡拉两套联盟

use*_*318 15 functional-programming scala

这里链接的问题,我在Scala中找到了Union的实现:

def union(a: Set, b: Set): Set = i => a(i) || b(i)
Run Code Online (Sandbox Code Playgroud)

和Set是类型的函数:

type Set = Int => Boolean
Run Code Online (Sandbox Code Playgroud)

现在我明白在Scala中,函数在这里从Int映射到Boolean,我进一步理解了这个语句是如何执行的:

a(i) || b(i)
Run Code Online (Sandbox Code Playgroud)

但我不明白的是'我'在这里.它从何而来?当它找到to sets之间的匹配时,它返回true,如果确实如此,我在哪里过滤它?

Mic*_*ley 18

返回的Set(只是一个函数)union需要一些整数作为参数; 你必须给它一个任意的名字,以便你可以在函数体中引用它.如果你编写这样的函数可能会更有意义:

def union(a: Set, b: Set): Set = {
  (i) => a(i) || b(i)
}
Run Code Online (Sandbox Code Playgroud)

如果你这样写它可能会更有意义:

def union(a: Set, b: Set): Set = {
  // The union of two sets is a new function that takes an Int...
  def theUnion(i: Int): Boolean = {
    // and returns true if EITEHR of the other functions are true
    a(i) || b(i)
  }

  // Now we want to return the NEW function
  theUnion
}
Run Code Online (Sandbox Code Playgroud)

同样,i是任意的,可以用任何变量替换:

def union(a: Set, b: Set): Set = item => a(item) || b(item)
Run Code Online (Sandbox Code Playgroud)

[更新]

因为我们将集合表示为函数,所以不需要迭代以查看它们是否包含数字.例如,这是一个包含以下任何数字的集合-5:

val belowNegFive: Set = (i) => i < -5
Run Code Online (Sandbox Code Playgroud)

当我们用一个数字调用该函数时,它会告诉我们该数字是否在集合中.请注意,我们在任何时候都没有真正告诉它集合中的具体数字:

scala> belowNegFive(10)
res0: Boolean = false

scala> belowNegFive(-100)
res1: Boolean = true

scala> belowNegFive(-1)
res2: Boolean = false
Run Code Online (Sandbox Code Playgroud)

这是另一套包含50和之间的任何数字100:

val fiftyToHundred: Set = (i) => i >= 50 && i <= 100

scala> fiftyToHundred(50)
res3: Boolean = true

scala> fiftyToHundred(100)
res4: Boolean = true

scala> fiftyToHundred(75)
res5: Boolean = true

scala> fiftyToHundred(49)
res6: Boolean = false
Run Code Online (Sandbox Code Playgroud)

现在,联盟中套belowNegFivefiftyToHundred将包含任何数字,无论是低于-5 之间50100.我们可以通过返回一个函数来轻松地在代码中表示这一点,如果其他两个函数中的任何一个返回true,则返回true.

scala> val unionOfBoth: Set = (i) => belowNegFive(i) || fiftyToHundred(i)
unionOfBoth: Int => Boolean = <function1>

scala> unionOfBoth(-10)
res7: Boolean = true

scala> unionOfBoth(50)
res8: Boolean = true

scala> unionOfBoth(0)
res9: Boolean = false
Run Code Online (Sandbox Code Playgroud)

union您问题中的函数只是一种在任何两个集合中一般应用此模式的方法.


Shr*_*rey 11

让我们说,我们有一个名为对象SoSet给出

object SoSet {
    type Set = Int => Boolean
    val a : Set = ???
    val b : Set = ???
    def isItem(item : Int) = a(item) || b(item)
}
Run Code Online (Sandbox Code Playgroud)

签名isItem是由Int => Booleana 给出的Set.到现在为止还挺好.

但现在我们只想返回函数 isItem(即a Set).

所以我们union为此定义函数(现在没有参数.我们稍后会添加它).

object SoSet {
    //..   
     def union : Set = isItem // returns the function isItem
}
Run Code Online (Sandbox Code Playgroud)

现在让我们重构isItem一个匿名函数.

object SoSet {
    //..   
    def union : Set = {
      (item : Int) => a(item) || b(item)
    }
}
Run Code Online (Sandbox Code Playgroud)

让我们Set a and bobject SoSet参数转移到def union.重构itemi.

object SoSet { 
   type Set = Int => Boolean
   def union(a : Set, b : Set) : Set = (i : Int) => a(i) || b(i)
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

 val s1 = Set(1, 2, 3)                           
 val s2 = Set(2, 3, 4)     
 val s3 = union(s1, s2) //  returns the function..  Int => Boolean = <function1>
 s3(2)  // invokes the function & checks if 2 is present in the union     
Run Code Online (Sandbox Code Playgroud)