Scala set function - scala

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)

Related

Scala function composition totalFn(partialFn(totalFn(x)))

I was trying to compose three functions with only the middle one being a PartialFunction. I would expect the resulting type to be PartialFunction as well.
Example:
val mod10: Int => Int = _ % 10
val inverse: PartialFunction[Int, Double] = { case n if n != 0 => 1.0 / n }
val triple: Double => Double = _ * 3
val calc: Int => Double = mod10 andThen inverse andThen triple
However, calc is not defined on the whole of its domain. It will throw MatchError for every number divisible by 10.
What is the reason for returning a total function when at least one of the functions in the composition is partial?
Another example where composition of partial functions results in another partial function with incorrect domain conditions:
val inverse: PartialFunction[Double, Double] = { case n if n != 0 => 1.0 / n }
val arcSin: PartialFunction[Double, Double] = {
case n if math.abs(n) <= 1 => math.asin(n)
}
val calc: PartialFunction[Double, Double] = inverse andThen arcSin
I would expect the domain of calc to be (-Infinity, -1] union [1, Infinity) but calling calc.lift(0.5) will throw a MathError instead of returning None because the input is within the first function's domain.
Thanks,
Norbert
Example 1: What is the reason for returning a total function when at least one of the functions in the composition is partial?
It's because the first function in your first example is a total function (Function1) and its andThen method returns a Function1 regardless of whether the second function is total or partial:
def andThen[A](g: (R) => A): (T1) => A
My guess is that the Scala language design team prefers a more generalized returned value since PartialFunction is a subclass of Function and would rather let users derive specialized code as needed.
Example 2: calling calc.lift(0.5) will throw a MathError instead of returning None
From the PartialFunction API doc, composing two partial functions via andThen will return a partial function with the same domain as the first partial function:
def andThen[C](k: (B) => C): PartialFunction[A, C]
Thus, the resultant composed function disregards the fact that inverse(0.5) (i.e. 2.0) is outside the domain of the second partial function arcSin.
So, when composing a function (total or partial) with a partial function using andThen, how can we make it return a partial function with proper domain?
Similar to what's demonstrated in this SO Q&A, one can enhance andThen via a couple of implicit classes to restrict the domain of the resultant composed function to a subset of the first function's domain that return values within the partial function's domain:
object ComposeFcnOps {
implicit class TotalCompose[A, B](f: Function[A, B]) {
def andThenPartial[C](that: PartialFunction[B, C]): PartialFunction[A, C] =
Function.unlift(x => Option(f(x)).flatMap(that.lift))
}
implicit class PartialCompose[A, B](pf: PartialFunction[A, B]) {
def andThenPartial[C](that: PartialFunction[B, C]): PartialFunction[A, C] =
Function.unlift(x => pf.lift(x).flatMap(that.lift))
}
}
Testing with the example functions:
import ComposeFcnOps._
val mod10: Int => Int = _ % 10
val inverse1: PartialFunction[Int, Double] = { case n if n != 0 => 1.0 / n }
val triple: Double => Double = _ * 3
val calc1 = mod10 andThenPartial inverse1 andThen triple
// calc1: PartialFunction[Int,Double] = <function1>
calc1.isDefinedAt(0)
// res1: Boolean = false
val inverse2: PartialFunction[Double, Double] = { case n if n != 0 => 1.0 / n }
val arcSin: PartialFunction[Double, Double] = {
case n if math.abs(n) <= 1 => math.asin(n)
}
val calc2 = inverse2 andThenPartial arcSin
// calc2: PartialFunction[Double,Double] = <function1>
calc2.isDefinedAt(0.5)
// res2: Boolean = false
calc2.lift(0.5)
// res3: Option[Double] = None
I think the error is your only expecting non-zero value.
{ case n if n != 0 => 1.0 / n }
then what if it will equal to zero then that is the cause of match Error..
{
case n if n != 0 => 1.0 / n // non-zero value.
case n if n == 0 => // zero value.
}
Hope it helps.
andThen is defined on Function1, and simply isn't designed to compose partial functions. Therefore, I recommend lifting them to total functions before using it.
val calc = Function.unlift(mod10 andThen inverse.lift andThen (_.map(triple)))
And
val calc = Function.unlift(inverse.lift andThen (_.flatMap(arcSin.lift)))

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 function => as parameter

Could anybody kindly explain to me why the following
/**
* Returns a set transformed by applying `f` to each element of `s`.
*/
def map(s: Set, f: Int => Int): Set = x => exists(s, y => f(y) == x)
is not equivalent to
def map(s: Set, f: Int => Int): Set = x => exists(s, f(x))
where "exists" is a function that returns whether there exists a bounded integer within s(the first argument) that satisfies p(the second argument).
Why do you need to specify "y => f(y) == x"? Thanks a million!
exists's second argument has the type Int => Boolean (right?), in other words, it expects a function from Int to Boolean. Now, f(x) doesn't conform to that type - it has the type Int. So - y => f(y) == x creates a function with the correct type, that returns true if its input equals x.
If the excess characters bug you - you can also shorten it a bit using the anonymous argument '_':
def map(s: Set, f: Int => Int): Set = x => exists(s, f(_) == x)

Scala Predicates, and Filter functions?

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.