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.
Related
This question already has answers here:
Understanding Currying in Scala
(3 answers)
Closed 4 years ago.
def sum(f: Int => Int): (Int, Int) => Int = {
def sumF(a: Int, b: Int): Int =
if (a > b) 0
else f(a) + sumF(a + 1, b)
sumF
}
def sumCubes = sum(a => a * a * a)
sumCubes // output Function2
sumCubes(1,10) // output 3025.
sumCubes() // doesn't work
I feel I dont understand currying well enough. In the first statement , we are calling sumCubes without parameters , hence sum gets called with the anonymous function as parameter and returns a function2.
Whats really happening in 2nd and 3rd invocation ,
Why are we able to do
sum(a => a * a * a)(1,10)
but not
sumCubes()(1,10)
My understanding is that in sum(a => a * a * a)(1,10) , we are partially applying sum to the anonymous function, which returns a Function2 ,which is applied to the second pair of parameters (1,10) and hence we are getting 3025,
However the same should happen in case of sumCubes()(1,10) , invoking sumCubes without parameters first , would inturn invoke sum with the anonymous function and the Function2 returned would be applied to (1,10)
Why does sumCubes(1,10) work but not sumCubes()(1,10) , shouldn't sumCubes and sumCubes() mean the same thing , invocation of function sumCubes. Also if a simple reference sumCubes is invoking it , how can I pass it around. I feel like I am not understanding something fundamental about Scala.
Scala's methods can have multiple argument lists.
For example, here is a method foo that has ten argument lists, of which the first seven are empty:
def foo()()()()()()()(a: Int)(b: Int)(c: Int): Int = a + b + c
You can invoke it as follows:
println(foo()()()()()()()(1)(20)(300))
and it will print 321.
Note that when you invoke a method, the number of argument lists, as well as the number of arguments in each list (and also their types) have to match the declaration.
Another example. The following method has two argument lists:
def bar(i: Int)(f: Int => Int) = f(i)
you can invoke it as follows:
bar(42)(x => x * x)
but not as
bar()(x => x * x)
bar()(42)(x => x * x)
bar(42)()
or anything like it.
Completely analogously, if you have defined a method with zero argument lists
def baz = (x: Int) => x * x
then you must invoke it with zero argument lists too:
baz
Since it returns an Int => Int function, you can of course apply the result to an Int:
baz(42)
which is the same as (baz)(42), but you cannot do the following:
baz()(42)
because baz itself has no argument lists, and () does not contain a single integer argument.
Note that all of the above is actually a simplification: under certain circumstances, methods that have an empty argument list can be called without parentheses, i.e. def foo(): Unit = ... can be invoked as foo, without (). This is a somewhat strange feature, and I can't say exactly why it's there. My best guess would be: it has something to do with java-interop, where you really want to omit parentheses on zero-ary getters.
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.
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.
w.r.t Currying in scala, partly I understood below sample code.
def product1(f:Int => Int )(a:Int, b:Int):Int = {
println()
if(a > b ) 1
else
f(a) * product1(f)(a+1, b)
}
product(x => x * x) (3, 4)
Out of it., I am bit confused with
product1(f)
in
product1(f)(a+1, b)
Just need explanation, what goes on here.... :( and how to pronounce verbally while explaining...
Thanks in advance..
product1 has two parameter lists. product1(f) is the application of f which is a function of kind Int => Int. If you were only to call product1(f) like so:
product1(f)
without the second parameter list, you'd get a so-called partially-applied function, i.e. a function which doesn't have all of its parameters bound (you'd still need to provide it with a and b)
Look at the parameter declaration:
f:Int => Int
f is a function that maps an Int to an Int -- it takes an Int as an argument and returns an Int. An example is given:
x => x * x
returns the square of its argument.
product1(x => x * x) (3, 4)
returns the product of f(3) .. f(4) = 3*3 * 4*4
BTW, this isn't really an example of currying, since all the arguments are given. Currying would be something like
val prodSquare = product1(x => x * x)
Then,
prodSquare(1, 5)
yields 1*1 * 2*2 * 3*3 * 4*4 * 5*5
For most idiomatic purposes I've seen, you may as well think of your function as having just one parameter list. Multiple parameter lists are used mostly for type inference purposes in generic functions, since type inference is done one parameter list at a time, rather than using Hindley-Milner/Algorithm W to infer the type of everything at once. Some other language features work on individual parameter lists, such as implicit parameters and implicit use of braces in place of parentheses for single-parameter parameter lists, etc.
Functions with multiple parameter lists are called in a similar way to a curried functions from a syntactic perspective, but by default, the intermediate functions aren't created. In fully curried style, each function takes only at most one argument and returns one result (which might happen to be another function, which expects on argument, and so forth). Technically, currying the function would be:
def product2(f: Int => Int): Int => Int => Int = {
a: Int => {
b: Int => {
if(a > b ) 1
else f(a) * product2(f)(a+1)(b)
}
}
}
For completeness, you can treat a function with multiple parameter lists as a curried function by using an underscore after a complete parameter list. In your original example, you'd do product1(f)_, which would return a function of type (Int, Int) => Int.
In researching this question, I came upon another SO question worth checking out to understand this aspect of the language better.
I have a very simple example of a set s1 {1, 2} and I want to apply a predicate p > 1 on it. Now I have implemented this function, and it is giving me correct results.
def filter(s: Set, p: Int => Boolean): Set = {(i: Int) => s(i) && p(i)}
Where definition of set is
type Set = Int => Boolean
But is there a more elegant way of doing it in Scala?
Using this course's definition of what a Set is, your answer is very elegant.
Since the predicate is in fact a Set too, filter could have been much more terse by reusing the intersect function:
/**
* Returns the intersection of the two given sets,
* the set of all elements that are both in `s` and `t`.
*/
def intersect(s: Set, t: Set): Set = ???
/**
* Returns the subset of `s` for which `p` holds.
*/
def filter(s: Set, p: Int => Boolean): Set = intersect(s, p)
I left the intersect implementation out because the Coursera Honor Code prevents sharing assignment answers.