Search code examples
scalasetaliaspredicateforall

Scala filter on all elements of an alias Set


Here is the question.

I have this type Set:

type Set = Int => Boolean

Which i can use like this:

val belowNegFive: Set = (i) => i < -5
belowNegFive(10)

I mean to return a bool depending if the elem 10 pertains to the set of numbers below -5.

  1. I have this code, which returns the subset of s for which p holds.
def filter(s: Set, p: Int => Boolean): Set = (e: Int) => s(e) && p(e)

Q1: How do I know p(e) tells me that the int e satisfies the predicate p?

  1. I have this fc, which returns whether all bounded integers within s satisfy 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: Why do all a > bound simply satisfy the condition of the predicate by default? Or true is just a stop condition? I am not sure why this fc does not return an infinite loop. Just an infinite list of Booleans, and the last Booleans are "true, true, true ..." for all a > bound.

Q3: And i do not see in which point it uses && between resulting Booleans in order to say yes, all bounded integers within s satisfy p.

thank you


Solution

  • For Q1: p is a function which takes an integer and returns a boolean. My predicate can be something like, the number should be less than -10. My set can be, it should be less than -5. filter will return that custom set for which both hold.

      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
    

    For Q2:

    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)
    }
    

    It's a stop condition. forall dictates that if for all integers b/w -1000 to 1000 (bound), if set contains the integer and predicate holds, it is true. AS you can see, in last line, the check is started from -1000 (iter(-bound)).

    Q3: what will truth table for set and predicate look like?

    set  | predicate | should continue checking?  
    ____________________________________________
    true | true      | yes
    false| true      | yes 
    true | false     | no 
    false| false     | yes
    

    As you can see, only condition it should return false is the third one, which is the else if condition. For all others, it continues to check with the next integer for presence in set and predicate.