Scala Else return function - scala

I'm taking the Coursera FP Principles in Scala course, and I'm having trouble with the last function in the week 2 assignment. I don't want the answer, but rather some help in understanding Scala functional composition. I think I have the right idea as to how to solve the problem, I'm just getting tripped up on the Scala-specific part.
The gist is: We've been given a type alias, defined as such:
type Set = Int => Boolean
Which I've interpreted to mean a Set is a function that takes an Int and returns a Bool.
We've also been tasked with finishing the function singletonSet, which takes an int and returns a Set. I've written it as such
def singletonSet(x: Int): Set = Set(x)
val three = singletonSet(3)
three(3) //True
three(5) //False
The function I'm having trouble with is the Map function, which has this signature:
def map(s: Set, p: Int => Int): Set
Which I've interpreted to mean A function that takes a set, transforms its elements with function P, and returns a new Set.
The pesudocode: Map returns a function that takes an int, and if that int exists in Set s, return a new Set with the transformed int X (or p(x)
The actual code that's breaking:
def map(s: Set, p: Int => Int): Set = {
x =>
if (s(x)) singletonSet(p(x))
else p(x) => false
}
The error that I'm getting with this format is:
error: not a legal formal parameter.
Note: Tuples cannot be directly destructured in method or function parameters.
Either create a single parameter accepting the Tuple1,
or consider a pattern matching anonymous function: `{ case (param1, param1) => ... }
else p(x) => false
I'm not grokking what's wrong with my implementation. A friend wrote my logic out in Haskell and found it to be successful, so I think my algorithm is correct (although I could be wrong). I'm struggling with the Scala implementation details. Any advice or guidance is much appreciated.

Remember that you're dealing with a Set here, and Set is defined as a function that converts an Int to a Boolean. Therefore, your function needs to return the same thing:
def map(s: Set, p: Int => Int): Set = {
x =>
if (s(x)) singletonSet(p(x)) // Returns a Set
else p(x) => false // Returns a Boolean
}
We can see that despite the input, you have two different output cases, which we know must be wrong. Now, lets also recall that you have other functions, and your definition of set and 'expand' what you're building:
def map(s: Set, p: Int => Int): (Int) => (Boolean) //Expand 'Set' to int->boolean
= (x: Int) => (Something that returns a boolean)
Your job is to figure out what that 'something' is, based on the semantics of map. I highly recommend looking around at other functions that return a boolean and ask how they might apply here. Specifically, you're looking for a function that will, for any integer provided, give you a transformation if that integer exists within the original set.

Related

Returning a partially applied function in Scala

Having a function f defined as:
def f(i1: Int, i2: Int)(i3: Int) = i1 + i2 + i3
It is possible to define a partially applied function as follows using _:
val f12 = f(1, 2) _ // f12: Int => Int = <function>
f12(3) // res0: Int = 6
Now when I return a partially applied function from a function, I do not need to use _:
def f23(f: (Int, Int) => Int => Int) = f(2, 3) // f23: (f: (Int, Int) => Int => Int)Int => Int
val f23f = f23(f) // f23f: Int => Int = <function>
f23f(4) // res1: Int = 9
If I place _ at the f23 definition I will get an Error:
def f23(f: (Int, Int) => Int => Int) = f(2, 3) _
Error:(6, 49) _ must follow method; cannot follow Int => Int
def f23(f: (Int, Int) => Int => Int) = f(2, 3) _
What is the reason for this inconsistency?
f is a method, not a function. You can read about some of the differences here.
f12 is a function derived from f via eta-expansion. It is not a partial function. A PartialFunction is a function defined over a limited domain of input values. If, say, f12 was defined only for Int values less than 500, for example, and undefined for input values greater than 500, then it would be a partial function.
def f23(f: (Int, Int) => Int => Int) = f(2, 3) _
This fails because f, as defined here, is a function that takes 2 Int values and returns a function that takes an Int and returns an Int. In this situation what is the underscore supposed to be standing in for? f(2,3) is a complete invocation that returns an Int=>Int function. It's a bit like writing 5 + 7 _. It's not clear what the _ is substituting for.
You can, on the other hand, do this: ... = f(2,3)(_). Then it's clear that the returned function is being invoked with a missing, i.e. _, parameter. Which is the same thing as: ... = f(2,3).
This is by design in Scala to prevent developer confusion.
If you tell the compiler the type of f12 explicitly it will work as you expect:
`val f12:Int=>Int = f(1, 2)`
This is explained by the language originator (Martin Odersky):
Why the trailing underscore?
Scala's syntax for partially applied functions highlights a difference in the design trade-offs of Scala and classical functional languages such as Haskell or ML. In these languages, partially applied functions are considered the normal case. Furthermore, these languages have a fairly strict static type system that will usually highlight every error with partial applications that you can make. Scala bears a much closer relation to imperative languages such as Java, where a method that's not applied to all its arguments is considered an error. Furthermore, the object-oriented tradition of subtyping and a universal root type accepts some programs that would be considered erroneous in classical functional languages.
For instance, say you mistook the drop(n: Int) method of List for tail(), and you therefore forgot you need to pass a number to drop. You might write, "println(drop)". Had Scala adopted the classical functional tradition that partially applied functions are OK everywhere, this code would type check. However, you might be surprised to find out that the output printed by this println statement would always be ! What would have happened is that the expression drop would have been treated as a function object. Because println takes objects of any type, this would have compiled OK, but it would have given an unexpected result.
To avoid situations like this, Scala normally requires you to specify function arguments that are left out explicitly, even if the indication is as simple as a `_'. Scala allows you to leave off even the _ only when a function type is expected.

Function that takes a function and list and returns Boolean

I am relatively new to Scala functional programming. I have been following a few tasks, however, finding difficult to understand or implement the concept below.
Basically, I want write a function which takes a list and a function, and returns true if the function returns true for at least one
item in the list. An example would be: hasMatch(isEven,List(1,2,3,5)) will return true, but hasMatch(isEven,List(1,3,5)) will return false.
A sample solution or hint is provided with the problem, as seen below:
def hasMatch (fn:(Int)=>Boolean,lst:List[Int]):Boolean = {
lst.foreach ((x:Int) => if (fn(x)) return true)
return false
}
Could someone please explain the concept behind it or ways to implement it.
Your isEven function is going to determine the outcome of the hasMatch function. So assuming that your isEven function is defined like this:
def isEven(x: Int): Boolean = x % 2 == 0
You can now define your hasMatch function like this:
def hasMatch(fn: Int => Boolean, l: List[Int]): Boolean = {
l.exists(elem => fn(elem))
}
You then call the function like this:
hasMatch(isEven, List(1,2,3,5))
def hasMatch(fn: Int => Boolean, lst: List[Int]): Boolean = lst.exists(fn)
The exists function has the same semantics as what you're after - it returns true if fn returns true for at least one element, false otherwise.
The biggest problem with your implementation: return is a really bad thing in scala, and should (almost) never be used.
Also, there are more idiomatic ways to do what you want, rather than spelling out the imperative loop with foreach.
Here is one possibility:
def hasMatch[T](lst: List[T])(fn: T => Boolean) = lst.exists(fn)
I added a type parameter to your definition, so that it works for any type, not just Int. Also, I made fn the last argument, and moved it into a separate list. It makes it easier to pass anonymous functions in:
if (hasMatch(List(1,2,3,4,5)) { _ > 5 }) println("There are elements greater than five")

In Scala how to curry existing function with single argument and pass to a higher order function?

I have a function
def myInnerFunc(a: Int): Int = a
now I want to pass it to a higher order function and I want it to be passed to the higher order function preinitialized with argument so need to first call my inner function with the proper parameter and only then I can pass it to the higher order function which would make up something like:
def myHigherOrderFunction(func: Int => Int): Int = {
func()
}
So I need to complete following code
myInnerFunc(1) // hmm fix this will actually call my innner function I just want to preinitialize it with one.
func() // didn't work for me how do i run my preinitialized with argument func Int => Int
How do I preinitialize myInnerFunc with argument 1 without running it?
How do I run func() from within the higher order function?
I'm not sure how to do that and couldn't really find relevant docs, can anyone please provide an example? (all examples I saw were with multiple arguments I have a single one)
If you just want to somehow delay the evaluation of f by wrapping it inside another function you can use anonymous functions:
val outer = { () => f(1) }
The reason single parameter currying is not that frequent is because this, given there are no side effects, yields a constant, which is not that exciting or useful.
Let's take your questions in reverse order:
How do I run func() from within the higher order function?
If the argument has already been provided, it isn't needed again, so the myHigherOrderFunction should look something like this:
def myHigherOrderFunction(func: Unit => Int): Int = { func() }
How do I preinitialize myInnerFunc with argument 1 without running it?
So you need something of type Unit => Int.
val thunk: Unit => Int = { _ => myInnerFunc(argument) }

Difference between currying and higher-order functions

Looking at Programming in Scala (control abstraction) I saw these two examples that have the same effect:
1. Higher-Order Function
def withPrintWriter(file: File, op: PrintWriter => Unit) {
val writer = new PrintWriter(file)
try {
op(writer)
} finally {
writer.close()
}
}
2. Currying function
def withPrintWriter(file: File)(op: PrintWriter => Unit) {
val writer = new PrintWriter(file)
try {
op(writer)
} finally {
writer.close()
}
}
What is the difference between them? Can we always achieve the same result in both ways?
The concepts of higher-order functions and curried functions are generally used in an orthogonal way. A higher-order function is simply a function that takes a function as an argument or returns a function as a result, and it may or may not be curried. In general usage, someone referring to a higher-order function is usually talking about a function that takes another function as an argument.
A curried function, on the other hand, is one that returns a function as its result. A fully curried function is a one-argument function that either returns an ordinary result or returns a fully curried function. Note that a curried function is necessarily a higher-order function, since it returns a function as its result.
Thus, your second example is an example of a curried function that returns a higher-order function. Here's another example of curried function that does not take a function as an argument, expressed in various (nearly equivalent) ways:
def plus(a: Int)(b:Int) = a + b
def plus(a: Int) = (b: Int) => a + b
val plus = (a: Int) => (b: Int) => a + b
Higher order functions are functions that either take functions as parameter or return functions or both.
def f(g: Int => Int) = g(_: Int) + 23
scala> f(_ + 45)
res1: Int => Int = <function1>
scala> res1(4)
res2: Int = 72
This is a higher order function, it takes a function as parameter and returns another function. As you can see, higher order functions are a pre-requisite for currying. The curry function looks like this:
def curry[A,B,C](f: (A,B) => C) = (a: A) => (b: B) => f(a,b)
scala> curry((a: Int, b: Int) => a+b)
res3: Int => (Int => Int) = <function1>
scala> res3(3)
res4: Int => Int = <function1>
scala> res4(3)
res5: Int = 6
So to answer your question: They are two different concepts, where the one (higher order functions) is the pre-requisit for the other (currying).
Semantically, there is one difference I can think of between a curried and a not curried function. With the non-curried version, when you call withPrintWriter, that's a single method call. With the curried version, it's actually going to be two method calls. Think of it like this:
withPrintWriter.apply(file).apply(op)
Other than that, I think a lot of people use currying in this kind of situation for style. Using currying here makes this look more like a language feature then just a custom function call because you can use it like this:
withPrintWriter(file){ op =>
...
}
Using it in that way is trying to emulate some sore of control structure from the language itself, but again, this is only really a style thing and it does come with the overhead of an additional method call.
You can use the non-curried version in almost the same way, but it's not as clean looking:
withPrintWriter(file, { op =>
...
})
EDIT
#drexin makes a good point in his answer that it's worth mentioning here for me. When you think of the signature of the curried version of the method, it's really:
Function1[File, Function1[PrintWriter, Unit]]
They are mostly the same, but there is a difference with regard to type inference. Scala is not able to infer types between arguments of a single method invocation, but it is able to infer types for multiple argument lists.
Consider:
def foo1[T](x : T, y : T => T) = y(x)
def foo2[T](x : T)(y : T => T) = y(x)
foo1(1, t => t + 1) //does not compile with 'missing parameter type'
foo2(1)(t => t + 1) //compiles
You can see some additional information in this answer : Multiple parameter closure argument type not inferred
Strictly speaking, the example you gave is not really curried, it just has multiple argument lists. It just happens that multiple argument list Scala functions look a lot like curried functions in many situations. However, when you call a multiple argument list function but don't fill in one or more argument lists, it's really an example of partial application, not currying. Calling a multiple argument list with all its arguments is just one function call, not one per argument list.
There are two use cases where multiple argument list functions are helpful. The first is the case of implicit parameters, since all implicit parameters have to be in their own argument list separate from any explicit parameters. The second use case is functions that accept other functions as parameters, since if a parameter that is a function is in its own argument list, you can leave off the parentheses and just use braces, making the function call look like some sort of control structure.
Other than that, the difference is purely cosmetic.

scala loan pattern, optional function param

I have a loan pattern that applies a function n times where 'i' is the incrementing variable. "Occasionally", I want the function passed in to have access to 'i'....but I don't want to require all functions passed in to require defining a param to accept 'i'. Example below...
def withLoaner = (n:Int) => (op:(Int) => String) => {
val result = for(i <- 1 to n) yield op(i)
result.mkString("\n")
}
def bob = (x:Int) => "bob" // don't need access to i. is there a way use () => "bob" instead?
def nums = (x:Int) => x.toString // needs access to i, define i as an input param
println(withLoaner(3)(bob))
println(withLoaner(3)(nums))
def withLoaner(n: Int) = new {
def apply(op: Int => String) : String = (1 to n).map(op).mkString("\n")
def apply(op: () => String) : String = apply{i: Int => op()}
}
(not sure how it is related to the loan pattern)
Edit Little explanation as requested in comment.
Not sure what you know and don't know of scala and what you don't undestand in that code. so sorry if what I just belabor the obvious.
First, a scala program consist of traits/classes (also singleton object) and methods. Everything that is done is done by methods (leaving constructor aside). Functions (as opposed to methods) are instances of (subtypes of) the various FunctionN traits (N the number of arguments). Each of them has as apply method that is the actual implemention.
If you write
val inc = {i: Int => i + 1}
it is desugared to
val inc = new Function1[Int, Int] {def apply(i: Int) = i + 1}
(defines an anonymous class extending Function1, with given apply method and creating an instance)
So writing a function has rather more weight than a simple method. Also you cannot have overloading (several methods with the same name, differing by the signature, just what I did above), nor use named arguments, or default value for arguments.
On the other hand, functions are first classes values (they can be passed as arguments, returned as result) while methods are not. They are automatically converted to functions when needed, however there may be some edges cases when doing that. If a method is intended solely to be used as a function value, rather than called as a method, it might be better to write a function.
A function f, with its apply method, is called with f(x) rather than f.apply(x) (which works too), because scala desugars function call notation on a value (value followed by parentheses and 0 or more args) to a call to method apply. f(x) is syntactic sugar for f.apply(x). This works whatever the type of f, it does not need to be one of the FunctionN.
What is done in withLoaner is returning an object (of an anonymous type, but one could have defined a class separately and returned an instance of it). The object has two apply methods, one accepting an Int => String, the other one an () => String. When you do withLoaner(n)(f) it means withLoaner(n).apply(f). The appropriate apply method is selected, if f has the proper type for one of them, otherwise, compile error.
Just in case you wonder withLoaner(n) does not mean withLoaner.apply(n) (or it would never stop, that could just as well mean withLoaner.apply.apply(n)), as withLoaner is a method, not a value.