Scala function => as parameter - scala

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)

Related

issue with by-name parameter in scala when using function literal [duplicate]

I'm struggling to write an anonymous function with by-name parameter. Here is what i tired.
val fun = (x: Boolean, y: =>Int) => if(x) y else 0
This fail with following error.
Error:(106, 31) identifier expected but '=>' found.
val fun = (x: Boolean, y: =>Int) => if(x) y else 0
^
Error:(109, 3) ')' expected but '}' found.
}
^
How ever same code as a standard function works.
def fun1(x: Boolean, y: =>Int) = if(x) y else 0
Any pointers ?
---------------Edit-----------------
I had a two part problem. senia answer solved the initial case. Suppose I have a function takes a function.
def xxx[A,B](f:(A,=>B)=>B)={}
As per senia solution it works.
val fun: (Int, =>Boolean) => Boolean = (x, y) => y
xxx[Int,Boolean](fun)
However I wanna get rid of the intermediate fun and call xxx with anonymous function. Doing
xxx((Int, =>Boolean) => Boolean = (x, y) => y)
Will not work. Any ideas how to do this ?
You could specify type of anonymous function, instead of types of parameters like this:
val fun: (Boolean, => Int) => Int = (x, y) => if(x) y else 0
scala> fun(false, {println("!"); 2})
res1: Int = 0
scala> fun(true, {println("!"); 2})
!
res2: Int = 2
=> Int is not a correct type name, it's a special syntax for by-name parameters in parameters block of method declaration or anonymous function type.
See SLS 4.6 Function Declarations and Definitions
ParamType ::= Type
| ‘=>’ Type
| Type ‘*’
In case you don't want to assign anonymous function to variable you could either use type inference like this:
xxx[Int, Boolean]{ (x, y) => y }
Or specify its type this way:
xxx({ (x, y) => y }: ((Int, => Boolean) => Boolean))

Currying in Scala, what are the types that make these statements compile?

So I have this function in Scala:
def f(a: Int)(b: Int)(c: Double)(d: Double): Double = a * c + b * d
The question is What are the three types that make the following statements compile.
def g: <Type1> = f(1)(2)(3.0)
def h: <Type2> = f(1)(2)
def k: <Type3> = f(1)
I'm still new to Scala and I am not really understanding the concept of currying. Maybe an answer to this question with some explanation will really help me. Thanks.
First, one main thing: function that takes two parameters a and b and returns a value c can be viewed as a function that takes an a and returns a function that takes b and returns c. This "change of point of view" is called currying.
Imagine a function that sums up two numbers. You give it 2 and 3, it returns 5. It can be viewed as a function that takes one number and returns a function from a number to a number. You give it a 2, it returns a function that takes some number and adds 2 to it.
Now, some types that you requested:
// pseudocode!
def g: Double => Double
= f(1)(2)(3.0) // we supply three params and are left with only one, "d"
= (d: Double) => 1 * 3.0 + 2 * d // we comply with g's type
def h: Double => Double => Double // or (Double, Double) => Double
= f(1)(2) // we supply two params and are left with two more, "c" and "d"
= (c: Double)(d: Double) => 1 * c + 2 * d // we comply with h's type
def k: Double => Double => Double => Double // or (Double, Double, Double) => Double
= f(1) // we supply one param and are left with three more, "b", "c" and "d"
= (b: Double)(c: Double)(d: Double) => 1 * c + b * d // we comply with k's type
Currying IMO is one of the most confusing concepts in Scala. The term itself comes from functional programming paradigm and, according to wikipedia, is
the technique of translating the evaluation of a function that takes
multiple arguments (or a tuple of arguments) into evaluating a
sequence of functions, each with a single argument.
which means that function call f(a, b, c) is represented by f(a)(b)(c). Looks like Scala? Not exactly. Here we have three function calls, each of them returns another function. Type of f (in Scala speak) is Int => (Int => (Double => (Double => Double))). Let's look at your f:
scala> def f(a: Int)(b: Int)(c: Double)(d: Double): Double = a * c + b * d
f: (a: Int)(b: Int)(c: Double)(d: Double)Double
As you see, there are no arrows here. What we have here is a method with multiple parameter lists. Method has no value and can't be assigned or passed anywhere, it belongs to an object. Function, on the other hand, is an object and can be assigned or passed to another method or function. In most cases omitting parameter lists is not allowed for methods:
scala> f(0)
<console>:01: error: missing argument list for method f
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `f _` or `f(_)(_)(_)(_)` instead of `f`.
There is one exception though as error message implies: if f(0) is placed in a functional context Scala will perform automatic eta-expansion, which means it will convert your method to a function:
scala> val fl: (Int => (Double => (Double => Double))) = f(0)
fl: Int => (Double => (Double => Double)) = $$Lambda$1342/937956960#43c1614
where eta-expansion means literally this:
scala> val fl: (Int => (Double => (Double => Double))) = (b => (c => (d => f(0)(b)(c)(d))))
fl: Int => (Double => (Double => Double)) = $$Lambda$1353/799716194#52048150
Another (explicit) way to convert a method to a curried function is by using placeholder (which will give you correct types right away):
scala> f _
res11: Int => (Int => (Double => (Double => Double))) = $$Lambda$1354/1675405592#4fa649d8
scala> f(0) _
res12: Int => (Double => (Double => Double)) = $$Lambda$1355/1947050122#ba9f744
Also be aware that:
def g: Int => (Double => (Double => Double)) = f(0)
is in fact
def g: Int => (Double => (Double => Double)) = (b => (c => (d => f(0)(b)(c)(d))))
i.e. it's a method g, which creates a function on the fly and returns it. So g(0) means "call method g without parameters, get back a function and apply it to 0".

Explain this implementation of the Y combinator in Scala?

This is a implementation of the Y-combinator in Scala:
scala> def Y[T](func: (T => T) => (T => T)): (T => T) = func(Y(func))(_:T)
Y: [T](func: (T => T) => (T => T))T => T
scala> def fact = Y {
| f: (Int => Int) =>
| n: Int =>
| if(n <= 0) 1
| else n * f(n - 1)}
fact: Int => Int
scala> println(fact(5))
120
Q1: How does the result 120 come out, step by step? Because the Y(func) is defined as func(Y(func)), the Y should become more and more,Where is the Y gone lost and how is the 120 come out in the peform process?
Q2: What is the difference between
def Y[T](func: (T => T) => (T => T)): (T => T) = func(Y(func))(_:T)
and
def Y[T](func: (T => T) => (T => T)): (T => T) = func(Y(func))
They are the same type in the scala REPL, but the second one can not print the result 120?
scala> def Y[T](func: (T => T) => (T => T)): (T => T) = func(Y(func))
Y: [T](func: (T => T) => (T => T))T => T
scala> def fact = Y {
| f: (Int => Int) =>
| n: Int =>
| if(n <= 0) 1
| else n * f(n - 1)}
fact: Int => Int
scala> println(fact(5))
java.lang.StackOverflowError
at .Y(<console>:11)
at .Y(<console>:11)
at .Y(<console>:11)
at .Y(<console>:11)
at .Y(<console>:11)
First of all, note that this is not a Y-combinator, since the lambda version of the function uses the free variable Y. It is the correct expression for Y though, just not a combinator.
So, let’s first put the part which computes the factorial into a separate function. We can call it comp:
def comp(f: Int => Int) =
(n: Int) => {
if (n <= 0) 1
else n * f(n - 1)
}
The factorial function can now be constructed like this:
def fact = Y(comp)
Q1:
Y is defined as func(Y(func)). We invoke fact(5) which is actually Y(comp)(5), and Y(comp) evaluates to comp(Y(comp)). This is the key point: we stop here because comp takes a function and it doesn’t evaluate it until needed. So, the runtime sees comp(Y(comp)) as comp(???) because the Y(comp) part is a function and will be evaluated only when (if) needed.
Do you know about call-by-value and call-by-name parameters in Scala? If you declare your parameter as someFunction(x: Int), it will be evaluated as soon as someFunction is invoked. But if you declare it as someFunction(x: => Int), then x will not be evaluated right away, but at the point where it is used. Second call is “call by name” and it is basically defining your x as a “function that takes nothing and returns an Int”. So if you pass in 5, you are actually passing in a function that returns 5. This way we achieve lazy evaluation of function parameters, because functions are evaluated at the point they are used.
So, parameter f in comp is a function, hence it is only evaluated when needed, which is in the else branch. That’s why the whole thing works - Y can create an infinite chain of func(func(func(func(…)))) but the chain is lazy. Each new link is computed only if needed.
So when you invoke fact(5), it will run through the body into the else branch and only at that point f will be evaluated. Not before. Since your Y passed in comp() as parameter f, we will dive into comp() again. In the recursive call of comp() we will be calculating the factorial of 4. We will then again go into the else branch of the comp function, thus effectively diving into another level of recursion (calculating factorial of 3). Note that in each function call your Y provided a comp as an argument to comp, but it is only evaluated in the else branch. Once we get to the level which calculates factorial of 0, the if branch will be triggered and we will stop diving further down.
Q2:
This
func(Y(func))(_:T)
is syntax sugar for this
x => func(Y(func))(x)
which means we wrapped the whole thing into a function. We didn’t lose anything by doing this, only gained.
What did we gain? Well, it’s the same trick as in the answer to a previous question; this way we achieve that func(Y(func)) will be evaluated only if needed since it’s wrapped in a function. This way we will avoid an infinite loop. Expanding a (single-paramter) function f into a function x => f(x) is called eta-expansion (you can read more about it here).
Here’s another simple example of eta-expansion: let’s say we have a method getSquare() which returns a simple square() function (that is, a function that calculates the square of a number). Instead of returning square(x) directly, we can return a function that takes x and returns square(x):
def square(x: Int) = x * x
val getSquare: Int => Int = square
val getSquare2: Int => Int = (x: Int) => square(x)
println(square(5)) // 25
println(getSquare(5)) // 25
println(getSquare2(5)) // 25
Hope this helps.
Complementing the accepted answer,
First of all, note that this is not a Y-combinator, since the lambda version of the function uses the free variable Y. It is the correct expression for Y though, just not a combinator.
A combinator isn't allowed to be explicitly recursive; it has to be a lambda expression with no free variables, which means that it can't refer to its own name in its definition. In the lambda calculus it is not possible to refer to the definition of a function in a function body. Recursion may only be achieved by passing in a function as a parameter.
Given this, I've copied the following implementation from rosetta code that uses some type trickery to implement Y combinator without explicit recursion. See here
def Y[A, B](f: (A => B) => (A => B)): A => B = {
case class W(wf: W => A => B) {
def get: A => B =
wf(this)
}
val g: W => A => B = w => a => f(w.get)(a)
g(W(g))
}
Hope this helps with the understanding.
I don't know the answer, but will try to guess. Since you have def Y[T](f: ...) = f(...) compiler can try to substitute Y(f) with simply f. This will create an infinite sequence of f(f(f(...))). Partially applying f you create a new object, and such substitution becomes impossible.

Implementing map for an intensionally-defined set in Scala

type Set = Int => Boolean
/**
* Returns whether all bounded integers within `s` satisfy `p`.
*/
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)
}
/**
* Returns whether there exists a bounded integer within `s`
* that satisfies `p`.
*/
def exists(s: Set, p: Int => Boolean): Boolean = !forall(s, (x => !p(x)))
/**
* Returns a set transformed by applying `f` to each element of `s`.
*/
def map(s: Set, f: Int => Int): Set = (x => exists(s, (y: Int) => f(y) ==
x))
so for this piece of code. I don't understand function map.
I see its input are 2 arguments, which are set and method f. But the "body" part, I tried so hard but still don't get it. And what is that "y", and why using f(y) == x makes it apply method f to set elemtns?
need some explanation for me.
thank you!
To be succinct:
If you say: val set2 = map(set1, f),
then set2(x) will returns true if and only if there exits y in set1 such as f(y) == x
That's exactly what exists(set1, y => f(y) == x) is checking.
To put it an other way, an integer is in set2 only if you can obtain it by applying f to an element of set1.
We can try to understand this piece of code by applying it backwards.
The map method here would return true for every given x and function f, if x is a result of the function f applied to the elements of the original set.
It is done by checking that if we go over the original map and apply f to every element of this map, at least one of them will be equal to x (that is what the part (x => exists(s, (y: Int) => f(y) == x)) does).
Regarding exists itself, it is a statement that if we go over all elements of the set (using forall method) with a given predicate p, for at least one of the elements this predicate will not be false (this is the part !forall(s, (x => !p(x)))).
And what is that "y"
exists takes a function Int => Boolean as its second argument. This function is (y: Int) => f(y) == x, and y is simply the name we give to its argument, same as x in x => !p(x).
and why using f(y) == x makes it apply method f to set elemtns?
This definition says "x is a member of map(s, f) when exists(s, y => f(y) == x). Now consider a simple case: s is the set {1, 2} represented by a function x => (x == 1) || (x == 2), and f = z => z + 1 over it. Then we have
s2 = map(s, z => z + 1) = x => exists(s, y => y + 1 == x)
by inlining f into definition of map. You can check that:
2 is a member of s2, i.e. s2(2) is exists(s, y => y + 1 == 2) is exists(s, y => y == 1) is true.
0 is not a member of s2, i.e. s2(2) is exists(s, y => y + 1 == 0) is exists(s, y => y == -1) is false.
Thinking a bit more, you should be able to list all members of s2, and then to generalize to any s and f.

Scala set function

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)