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.
Related
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.
In the following statement the val f is defined as a lambda that references itself (it is recursive):
val f: Int => Int = (a: Int) =>
if (a > 10) 3 else f(a + 1) + 1 // just some simple function
I've tried it in the REPL, and it compiles and executes correctly.
According to the specification, this seems like an instance of illegal forward referencing:
In a statement sequence s[1]...s[n] making up a block, if a simple
name in s[i] refers to an entity defined by s[j] where j >= i,
then for all s[k] between and including s[i] and s[j],
s[k] cannot be a variable definition.
If s[k] is a value definition, it must be lazy.
The assignment is a single statement, so it satisfied the j >= i criteria, and it is included in the interval of statements the two rules apply to (between and including s[i] and s[j]).
However, it seems that it violates the second rule, because f is not lazy.
How is that a legal statement (tried it in Scala 2.9.2)?
You probably tried to use this in the REPL, which wraps all contents in an object definition. This is important because in Scala (or better: on the JVM) all instance values are initialized with a default value, which is null for all AnyRefs and 0, 0.0 or false for AnyVals. For method values this default initialization does not happen, therefore you get an error message in this case:
scala> object x { val f: Int => Int = a => if (a > 10) 3 else f(a+1)+1 }
defined object x
scala> def x { val f: Int => Int = a => if (a > 10) 3 else f(a+1)+1 }
<console>:7: error: forward reference extends over definition of value f
def x { val f: Int => Int = a => if (a > 10) 3 else f(a+1)+1 }
^
This behavior can even lead to weird situations, therefore one should be careful with recursive instance values:
scala> val m: Int = m+1
m: Int = 1
scala> val s: String = s+" x"
s: String = null x
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.
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.
In Stanford Scala course I've come across the following assignment:
Exercise 1 – Sets as Functions:
In this exercise we will represent sets as functions from Ints to Booleans:
type Set = Int => Boolean
a) Write a function "set" that takes an Int parameter and returns a Set containing that Int.
b) Write a function "contains" that takes a Set and an Int as parameters and returns true if the Int is in the Set and false otherwise.
c) Write the functions "union", "intersect", and "minus" that take two Sets as parameters and return a Set.
d) Can you write a function "subset" which takes two Sets as parameters and returns true if the first is a subset of the second and false otherwise?
Solutions to the a, b and c are fairly trivial:
def set(i: Int): Set = n => n == i
def contains(s: Set, i: Int) = s(i)
def union(a: Set, b: Set): Set = i => a(i) || b(i)
def intersect(a: Set, b: Set): Set = i => a(i) && b(i)
def minus(a: Set, b: Set): Set = i => a(i) && !b(i)
But is there any elegant solution for d?
Of course, strictly speaking, the answer to d is "yes", as I can write something like:
def subset(a: Set, b: Set) = Int.MinValue to Int.MaxValue filter(a) forall(b)
but that's probably not the right way.
I don't think it's possible without iterating through all the integers. For a pseudo-proof, look at the desired type:
def subset: (a: Set, b: Set): Boolean
Somehow, we've got to produce a Boolean when all we have to work with are sets (a, b) of type Int => Boolean, and integer equality (Int, Int) => Boolean. From these primitives, the only way to get a Boolean value is to start with Int values. Since we don't have any specific Int's in our hands, the only option is to iterate through all of them.
If we had a magical oracle, isEmpty: Set => Boolean, the story would be different.
A final option is to encode "false" as the empty set and "true" as anything else, thus changing the desired type to:
def subset: (a: Set, b: Set): Set
With this encoding, logical "or" corresponds to the set union operation, but I don't know that logical "and" or "not" can be defined easily.
We have
Set A =
Returns the intersection of the two given sets,
the set of all elements that are both in `s` and `t`.
Set B =
Returns the subset of `s` for which `p` holds.
Isn't Set A is equivalent to Set B
def filter(s: Set, p: Int => Boolean): Set = intersect(s, p)
I agree with Kipton Barros, you would have to check all values for Ints since you want to prove that forall x, a(x) implies b(x).
Regarding the optimization of it, I'd probably write:
def subset(a: Set, b: Set) = Int.MinValue to Int.MaxValue exists(i => !a(i) || b(i))
since !a(i) || b(i) is equivalent to a(i) implies b(i)
Later on in the Coursera exercises bounded sets are introduced and then forall() and exists() as universal and existential quantifiers over the bounds. subset() was not in the exercises but is similar to forall. Here is my version of subset():
// subset(s,p) tests if p is a subset of p returning true or false
def subset(s: Set, p: Set): Boolean = {
def iter(a: Int): Boolean = {
if (a > bound) { true
} else if (contains(p, a)) {
if (contains(s, a)) iter(a + 1) else false
} else iter(a+1)
}
iter(-bound)
}
Here is another version of it using contains function:
def union(s: Set, t: Set): Set = x => contains(s,x) || contains(t,x)
def intersect(s: Set, t: Set): Set = x => contains(s,x) && contains(t,x)
def diff(s: Set, t: Set): Set = x => contains(s,x) && !contains(t,x)
def filter(s: Set, p: Int => Boolean): Set = x => contains(s, x) && p(x)
If there are two sets A and B, then A intersect B is a subset of A and B. Mathematically proven: A ∩ B ⊆ A and A ∩ B ⊆ B. Function can be written like this:
def filter(s: Set, p: Int => Boolean): Set = x => s(x) && p(x)
Or
def intersect(s: Set, t: Set): Set = x => s(x) && t(x)
def filter(s: Set, p: Int => Boolean): Set = intersect(s,p)