Unsure how this union function on Sets works - scala

I'm trying to understand this def method :
def union(a: Set, b: Set): Set = i => a(i) || b(i)
Which is referred to at question : Scala set function
This is my understanding :
The method takes two parameters of type Set - a & b
A Set is returned which the union of the two sets a & b.
Here is where I am particularly confused : Set = i => a(i) || b(i)
The returned Set itself contains the 'or' of Set a & b . Is the Set 'i' being populated by an implicit for loop ?
Since 'i' is a Set why is it possible to or a 'set of sets', is this something like whats being generated in the background :
a(i) || b(i)
becomes
SetA(Set) || SetB(Set)

Maybe what's confusing you is the syntax. We can rewrite this as:
type Set = (Int => Boolean)
def union(a: Set, b: Set): Set = {
(i: Int) => a(i) || b(i)
}
So this might be easier to sort out. We are defining a method union that takes to Sets and returns a new Set. In our implementation, Set is just another name for a function from Int to Boolean (ie, a function telling us if the argument is "in the set").
The body of the the union method creates an anonymous function from Int to Boolean (which is a Set as we have defined it). This anonymous function accepts a parameter i, an Int, and returns true if, and only if, i is in set a (a(i)) OR i is in set b (b(i)).

If you look carefully, that question defines a type Set = Int => Boolean. So we're not talking about scala.collection.Set here; we're talking Int => Booleans.
To write a function literal, you use the => keyword, e.g.
x => someOp(x)
You don't need to annotate the type if it's already known. So if we know that the r.h.s. is Int => Boolean, we know that x is type Int.

No the set is not populated by a for loop.
The return type of union(a: Set, b: Set): Set is a function. The code of the declaration a(i) || b(i) is not executed when you call union; it will only be executed when you call the result of union.
And i is not a set it is an integer. It is the single argument of the function returned by union.
What happens here is that by using the set and union function you construct a binary tree of functions by combining them with the logical-or-operator (||). The set function lets you build leafs and the union lets you combine them into bigger function trees.
Example:
def set_one = set(1)
def set_two = set(2)
def set_three = set(2)
def set_one_or_two = union(set_one, set_two)
def set_one_two_three = union(set_three, set_one_or_two)
The set_one_two_three will be a function tree which contains two nodes: the left is a function checking if the passed parameter is equal to 3; the right is a node that contains two functions itself, checking if the parameter is equal to 1 and 2 respectively.

Related

scala coursera functional programing assignment FunSets

I have undergoing the functional programming course by martin odersky in scala on coursera.
However, I am unable to understand the solutions to the 2nd Assignment Funsets.scala.
type Set = Int => Boolean
/**
* Indicates whether a set contains a given element.
*/
def contains(s: Set, elem: Int): Boolean = s(elem)
/**
* Returns the union of the two given sets,
* the sets of all elements that are in either `s` or `t`.
*/
def union(s: Set, t: Set): Set = (e: Int) => s(e) || t(e)
Question In the above function what is e ? Where does it come from ? I know that the union function combines the two sets, but here what I understood from the method definition is that it takes 2 sets as input and returns the resulting union set, so where does e come from ?
/**
* Returns the intersection of the two given sets,
* the set of all elements that are both in `s` or `t`.
*/
def intersect(s: Set, t: Set): Set = (e: Int) => s(e) && t(e)
The same question would be applicable for intersect function.
Please can anybody explain me the operation of the above two functions i.e these two statements
(e: Int) => s(e) || t(e) and (e: Int) => s(e) && t(e)
def union(s: Set, t: Set): Set = (e: Int) => s(e) || t(e)
Let's break this down into small chunks.
def union() I'm defining a method that I'll call union.
(s: Set, t: Set) This method will take 2 parameters that I'll call s and t, both of type Set.
: Set This method will return a value of typeSet. Hold on...what's a Set?
type Set = Int => Boolean Ah, OK, Set is a function that takes an Int as a parameter and returns a Boolean as a result. Got it. Back to the union() method.
(e: Int) => s(e) || t(e) This is a function that takes a single parameter of type Int. I'm going to call that parameter e. When this function receives an Int it will be fed to both s and t. s and t are both type Set, which means that when fed an Int they return a Boolean. So then we'll have 2 Boolean values and they'll be OR'd together to produce a single Boolean, which matches the definition of a Set (Int in, Boolean out), so we're done.
So now let's create an example and see how this is put to use.
val setA:Set = x => x == 5 //this Set is true only for 5
val setB:Set = y => y == 2 //this Set is true only for 2
val setU = union(setA, setB) //setA is parameter s, setB is parameter t
setU(2) //'e' is now 2, this returns true
setU(5) //'e' is now 5, this returns true
setU(25) //'e' is now 25, this returns false
As mentioned in the video lecture... we are supposed to assign an anonymous function to the base function.
here, (x: Int) is not brought from somewhere, consider it as a function parameter of a different function.
ex:
def num(s: FunSet): FunSet = (x: Int) => x
this is similar to,
def function(x: Int) = x
def num(s: FunSet): FunSet = function
I Hope this helps future learners...! I had this doubt too...
e is called a parameter. A parameter gets bound to an argument when the function is applied to an argument.
For example, in the function
val f: Int ⇒ Int = i ⇒ i + 1
i is a parameter. If if apply the function referenced by f to an argument, say, 2, then inside the function, i is bound to the value of the argument, i.e. inside the function, dereferencing i evaluates to 2. Thus, applying the function referenced by f will evaluate to 3:
f(2)
//=> 3
Remember how a Set was defined in this assignment: it's merely a function that takes an Int and returns a Boolean. When you pass some Int to this function, the function returns true if the Int is in the Set, and false if it is not. In other words, this type of Set isn't really a collection so much as a definition of what it means for something to be in a given Set.
Now, what does calling union between two Sets do? Well it produces a Set whose members are in at least one of those two Sets. Remember, a Set is just a Int => Boolean function, so:
(e: Int) => s(e) || t(e)
is a function which takes some Int parameter, call it e, and returns true if EITHER s(e) is true OR t(e) is true. According to the union method declaration, what are s and t?
def union(s: Set, t: Set):
s is the FUNCTION describing whether an Int is in the Set s or not; likewise for t. Thus, s(e) || t(e) means that e must be in one or both Sets, for the union of the two Sets to return true- which is exactly what the definition fo a union is.

Functional Sets / Apply method

I have just started learning scala from the Coursera course by Martin Odesky. I am really struggling at the functional sets problem. The thing I am not able to catch is the union method-
object Functionalset {
type Set = Int => Boolean
def singletonSet(element: Int): Set = i => element == i
def union(a: Set, b: Set): Set = i => a(i) || b(i)
def main(args:Array[String]): Unit = {
print(singletonSet(2)(4));
}
}
In the union method I am essentially returning a function that takes an Int i and calls a(i) || b(i) to check whether i is in the set or not. The apply method is not defined anywhere. What does the a(i) do? Does it call the singletonSet(element:Int):Set? If so how?
What does the a(i) do? Does it call the singletonSet(element: Int)
No, there is no relationship between the two methods. a(i) in this particular case is simply the invocation of the function a, which is a function from Int to Boolean.
a is a of type Set, which is a type alias for a function from Int to Boolean (Int => Boolean with Scala syntax sugar).
Think of it like this:
def union(a: Int => Boolean, b: Int => Boolean): Int => Boolean = i => a(i) || b(i)
Since a is a function of type Function1[Int, Boolean], and so is b, calling a(i) is simply invoking the function with the passed value of i. Now, what may be confusing is the notation of:
i => a(i) || b(i)
Since union itself returns a function, it needs a placeholder for any future Int which may be passed in, this happens when you call singletonSet(2)(4), if we desugarize it a little, you have:
val intermidiateFunction: Int => Boolean = singletonSet(2)
val result: Boolean = intermidiateFunction(4)
Think of it as a two step invocation of a method, when you do the first invocation, you get back another function, and only when you call it the second time, you get back the result of the generated function.
Let's invoke union and see what happens:
scala> union(i => i < 3, i => i > 1)
res6: Set = <function1>
scala> val result = union(i => i < 3, i => i > 1)
result: Set = <function1>
scala> result(1)
res7: Boolean = true
union requires us to pass in two functions, so we create these simplified functions that check whether an Int is smaller than 3 or bigger than 1. The result of the first invocation is itself a function. When we'll now pass in an Int to the result, for example: result(1), we will check 1 < 3 || 1 > 1, which is equivalent to a(i) || b(i), where a is the first function, and b is the second.
In this lab, a set is defined as its characteristic function.
This translates into:
type Set = Int => Boolean
Which means that a Set is simply a function taking an Int and returning a Boolean (this is the characteristic function of the Set, an oracle which tells whether a given integer is in the set or not).
Your variable a, being a Set, is a function Int => Boolean, so a(i) is well-defined if i is an Int.
The characteristic function of a union of two sets is a function which returns true if its argument is in one of the two sets, false otherwise.

scala filter of 2 sets

def intersect(s: Set, t: Set): Set = (x => s(x) && t(x))
def filter(s: Set, p: Int => Boolean): Set = intersect(s, p)
I have this code.
I don't understand how does "filter" function be a valid one.
First of all, it uses intersect, but second parameter p is a method, not a Set as intersect function prototype requres.
Secondly, how does intersect(s, p) work as filter?
thanks
These are two different ways of looking at the same thing. As I mentioned in my previous answer, representing sets as their indicator functions makes lots of things more convenient, and one of those things is filtering.
Usually when we have a collection of some type A we can filter it using a predicate function A => Boolean that tells us whether or not we want to keep each element. In this case, the type of the predicate function is the same type we're using to represent the collection, and filtering is the same thing as taking the intersection of two sets.
To address your second question: intersect needs to return a function that will return true if the item is in both set s and set t and false otherwise. We can check that using the apply method on each (or in this case its syntactic sugar). The implementation is then a simple function literal (x => s(x) && t(x)) that takes an argument x and returns true if and only if x is in both sets.

Function literal - Need help in understanding a code snippet

I'm basically new to functional programming and scala, and the following question might possibly look stupid.
val f = (a:Int) => a+1
In the above snippet, should I consider f to be a function or a variable? Coming from a C/C++ background, the first thought that occurs is that f is a variable that stores the return value of the anonymous function, but I think that's not the correct way to interpret it Any explanation would be really helpful.
(Some of the terminologies I used above might be wrong with respect to scala/functional programming, kindly bear with it)
Here, f is a variable that stores a function. It's really no different from saying any of the following:
val a = 4 // `a` is a variable storing an Int
val b = "hi" // `b` is a variable storing a String
val f = (a:Int) => a+1 // `f` is a variable storing a function
You can also confirm this with the REPL:
scala> val f = (a:Int) => a+1
f: Int => Int = <function1>
So this is telling you that f has the type Int => Int. Or in other words, f is a function that takes one argument, an Int, and returns an Int.
Since f is a variable, you can call methods on it or pass it as an argument to functions that expect its type:
a + 3 // here I'm calling the `+` method on `a`, which is an Int
f(3) // here I'm calling the `apply` method on `f`, which is a function `Int => Int`
f(a) // the function `f` expects an `Int`, which `a` is
(1 to 3).map(f) // the `map` method expects a function from Int to Int, like `f`
Yes, like dhg said, f is a variable (that can't be changed) that stores a function.
However, there's a subtlety here:
... the first thought that occurs is that f is a variable that stores the
return value of the anonymous function
f actually stores the function, not the result. So you can give it different inputs, and get different outputs. So, you can use it like f(7) and then f(5). Functions in Scala are objects, so can be assigned to variables, passed as parameters, etc.
I recently posted about function literals, which may be helpful to you.
f is a value denoting a function literal.
In the statement, the right-hand-side is a function literal. The left-hand-side binds it to a name which is then called value (the val keyword is similar to let in LISP). Now the function is associated with the symbol f, so you can refer to that function by using this symbol f.
I disagree with the other answers which suggest that f should be called a variable. f is a value, because it is fixed to the right-hand-side term which is determined only once and cannot change. On the contrary a variable, introduced with var, allows you to re-assign values to a symbol:
var f = (i: Int) => i + 1
Where var begins a variable definition, f is the name or symbol of the variable, there could be an optional : ... defining type of the variable (if you leave that out, the type is automatically inferred from the assignment), and = ... defines the value initially assigned to the variable.
So when one says value, don't confuse this with a numeric constant, it is simply an entity that doesn't change. A function can be a value too, because f then always denotes this same identical function, even if you can feed that function with different arguments which yield different results.
Now with the var you can re-assign its right-hand-side:
f(2) // --> 3
f = (i: Int) => i * 2 // assign a new function to the variable f.
f(2) // --> 4
Functional programming is all about avoiding variables (re-assignments).
It is also possible to define a function without assigning it at all (to a value or a variable). The following defines such a function and immediately calls it with argument 4:
{ i: Int => i + 1 } apply 4 // --> 5
although that is seldom useful as a statement per se, but you will see 'plain' functions often when calling a method that expects a function argument. For instance
val s = List(1, 2, 3)
s.map { (i: Int) => i + 1 } // --> List(2, 3, 4)
s.map { _ + 1 } // equivalent
s.map( _ + 1 ) // equivalent

Union between sets

I am taking a Coursera Functional Programming in Scala class. This is the second week and I hit a wall. In the assignment we are working with Sets, but not the kind of Set we all meet in Java, for example. It is a Set that returns true if the value is in there and false otherwise. They say it's not a container, it's just a function.
To get it clear, I need your help. I don't want you to solve my assignment, it's just an example that I want to get the idea of what I should do.
/**
* 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(s: Set, elem: Int): Boolean = s(elem)
/**
* Returns the set of the one given element.
*/
def singletonSet(elem: Int): Set = Set(elem)
/**
* Returns the union of the two given sets,
* the sets of all elements that are in either `s` or `t`.
*/
def union(s: Set, t: Set): Set = ???
This is the code. In the singletonSet I guess the way to solve it is to return the Set(elem), right?
If that is good, how am I supposed to make the union between the two? I am not new to programming but I can't see any way to do it. Since I shouldn't return a "set" of numbers.
This is what another student told me about sets: "But all a "Set" is is a function that takes an Int and returns a Boolean (Int => Boolean). Any function that takes an Int and returns a Boolean fits the type 'Set'."
What I tried in the union function is to have something like:
def union(s: Set, t: Set): Set = (s | t) //value | not a member of Int => Boolean
Any help would be appreciated :)
It seems the wall you are hitting is that you are unfamiliar with defining functions in Scala. In this particular case you need to define functions of type Int => Boolean, they take an Int and return a Boolean.
Here are some examples of function literals of type Int => Boolean. Try them in the Scala console or the Scala IDE worksheet:
(x: Int) => true
(x: Int) => false
(x: Int) => x == 2
(x: Int) => x == 10
(x: Int) => x == 2 || x == 10
(x: Int) => x % 2 == 0
Then all you have to do for the assignment is to use the same syntax, starting with (x: Int) => and then translate the meaning of union, intersect, ... into the right hand side of the expression.
Part of learning is giving it a genuine effort. I believe you can resubmit the solution multiple times, so don't hesitate to submit and iterate if you don't get 10/10 on the first try. All you need is compiling code. Good luck!
A possible hint is to look at the types. Look at the Set type. It is actually a type alias to a function from Int into Boolean.
Thus, when you have two sets, you actually have two functions. How can you use them to provide a function that represent the union of these Set? It must be your starting point.