Sum of list arguments using currying in scala - scala

I am trying to get the sum of arguments using currying in Scala. This is a very basic question so please don't go hard on it.
If you can answer the question then please otherwise let it be:
object MultiSum extends App {
var res=0
def sum(f:Int=>Int)(x:Int*)={f(x)}
val a=List(1,2,3,4,5,6,7,8,9)
val b=sum(x=>x+x)(a:_*)
}
So val b will be storing the result of all the numbers passed in the List in var a
Thanks.

Well... first of all... I think you should call your function collect and not sum. Now, lets help you write this collect.
So... your collect function takes two arguments,
1 - A collector function.
2 - Things to accumulate.
So... your collector function needs to know two things... first is already collected and second is next item to collect... and it will produce the next collected.
Which means that for collection of Int, your collector function will have a signature (Int, Int) => Int.
So, your collect function should have following signature,
def collect(collector: (Int, Int) => Int)(items: Int*): Int = ???
Now... lets come to implement it.
1 - Using reduce
def collect(collector: (Int, Int) => Int)(items: Int*): Int =
items.reduce(collector)
2 - Using fold
def collect(collector: (Int, Int) => Int)(items: Int*): Int =
items.fold(0)(collector)
Now, you can use it like this,
val l = List(1,2,3,4,5,6,7,8,9)
val b = collect((i1, i2) => i1 + i2)(l: _*)

Related

Understanding Scala Currying

I am following a course from coursera where this example appears in the lecture but when I try and run it, it throws an error as follows:
missing argument list for method mapReduce in object HelloWorld
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing mapReduce _ or mapReduce(_,_,_)(_,_) instead of mapReduce.
var doo = mapReduce(x => x,(x,y)=>x*y,0)
Below is the code that I want to execute.
def mapReduce(map: Int => Int, combine: (Int,Int)=>Int,
zero: Int)(a: Int,b: Int): Int = {
if (a>b) zero
else combine(map(a), mapReduce(map,combine,zero)(a+1,b))
}
var doo = mapReduce(x => x, (x,y)=>x*y, 0)
println(doo(1,4))
mapReduce wants two argument lists, but your are giving it one.
Try this:
val doo = mapReduce(x => x, (x,y) => x*y, 0) _
or equivalently,
val doo = mapReduce(identity, _*_, 0) _
The _ in the end stands for the second argument list. It tells the compiler that you want the suffixed value to be taken as a functional value rather than an expression to be evaluated.
You can also give compiler a hint to make the conversion happen automatically by explicitly declaring the expected type of the expession:
val doo: (Int, Int) => Int = mapReduce(identity, _*_, 0)
And don't use vars. They are evil. Just pretend, there is no such keyword in scala, until you learn enough of the language to be able to recognize the extremely rare cases when it is actually needed.
You have to define a undescore parameter in order to create a curried function. Like this:
scala> var doo = mapReduce(x => x, (x,y)=>x*y, 0) _
doo: (Int, Int) => Int = <function2>
scala> println(doo(1,4))
0

Transforming a set - Scala Coursera exercise

I am working on the Coursera's Scala tutorials. One of the exercises asks to implement a map function to sets type that are defined as follows:
type Set = Int => Boolean. There was a stub for the function:
/**
* Returns a set transformed by applying `f` to each element of `s`.
*/
def map(s: Set, f: Int => Int): Set = ???
I thought that one can check if an element is in s, by doing the following:
(x: Int) => s(x). Which I am thinking should be equivalent to whatever the definition of a set is. Thus, if we want to apply transformation on the set, we can do:
(x: Int) => s(f(x)). And so the definition of function is:
def map(s: Set, f: Int => Int): Set = s(f(x)). But this gives me some weird set if I try it on:
def map(s: Set, f: Int => Int): Set = (x: Int) => s(f(x))
def toStringH(s: Set): String = {
val xs = for (i <- -bound to bound if contains(s, i)) yield i
xs.mkString("{", ",", "}")
}
def printSet(s: Set) { println(toStringH(s)) }
val squaredSet = map((x: Int) => (x> -3 & x<3), (x:Int) => (x+1))
printSet(squaredSet)
So I am wondering where I went wrong. Thanks.
I expect that you mean the progfun1 course by Martin Odersky and its Week 2 task. I believe that generally there is no solution for this problem (it requires finding a reverse function for a given function which I doubt is really possible) and the course authors know about that. Thus they added an additional restriction that you probably missed (I highlighted the important part):
Note that there is no direct way to find which elements are in a set. contains only allows to know whether a given element is included. Thus, if we wish to do something to all elements of a set, then we have to iterate over all integers, testing each time whether it is included in the set, and if so, to do something with it. Here, we consider that an integer x has the property -1000 <= x <= 1000 in order to limit the search space.
Although it is a comment for the forall task it is in the same section and just a few paragraphs above the map task.

loop until a condition stands in scala

I'd like to write a generic loop until a given condition stands, in a functional way.
I've came up with the following code :
def loop[A](a: A, f: A => A, cond: A => Boolean) : A =
if (cond(a)) a else loop(f(a), f, cond)
What are other alternatives ? Is there anything in scalaz ?
[update] It may be possible to use cats and to convert A => A into Reader and afterwards use tailRecM. Any help would be appreciated.
I agree with #wheaties's comment, but since you asked for alternatives, here you go:
You could represent the loop's steps as an iterator, then navigate to the first step where cond is true using .find:
val result = Iterator.iterate(a)(f).find(cond).get
I had originally misread, and answered as if the cond was the "keep looping while true" condition, as with C-style loops. Here's my response as if that was what you asked.
val steps = Iterator.iterate(a)(f).takeWhile(cond)
If all you want is the last A value, you can use steps.toIterable.last (oddly, Iterator doesn't have .last defined). Or you could collect all of the values to a list using steps.toList.
Example:
val steps = Iterator.iterate(0)(_ + 1).takeWhile(_ < 10)
// remember that an iterator is read-once, so if you call .toList, you can't call .last
val result = steps.toIterable.last
// result == 9
From your structure, I think what you are describing is closer to dropWhile than takeWhile. What follows is 100% educational and I don't suggest that this is useful or the proper way to solve this problem. Nevertheless, you might find it useful.
If you want to be generic to any container (List, Array, Option, etc.) You will need a method to access the first element of this container (a.k.a. the head):
trait HasHead[I[_]]{
def head[X](of: I[X]): X
}
object HasHead {
implicit val listHasHead = new HasHead[List] {
def head[X](of: List[X]) = of.head
}
implicit val arrayHasHead = new HasHead[Array] {
def head[X](of: Array[X]) = of.head
}
//...
}
Here is the generic loop adapted to work with any container:
def loop[I[_], A](
a: I[A],
f: I[A] => I[A],
cond: A => Boolean)(
implicit
hh: HasHead[I]): I[A] =
if(cond(hh.head(a))) a else loop(f(a), f, cond)
Example:
loop(List(1,2,3,4,5), (_: List[Int]).tail, (_: Int) > 2)
> List(3, 4, 5)

passing all arguments to a function as a single array

This is a Scala-specific question.
Assume that you have a function (which you cannot modify) of several inputs, e.g.:
def test(x1: Int, x2:Int, x3: Int, x4: Int, x5: Int) = {
//Some logic
}
And assume that you have all the inputs for that function in a single array, e.g.:
val inputs = Array(1, 2, 3, 4, 5)
Is there a way to call test with that single array of inputs without explicitly inserting individual array elements (as in test(inputs(0),inputs(1),inputs(2),inputs(3),inputs(4)))?
This is particularly important for the case when I don't know the number of inputs and the number of elements in the array in advance (but know that they match).
No that's not possible. It's possible to use an array for a function that expects varargs by using :_* syntax. Also, your question is contradictory:
the case when I don't know the number of inputs and the number of
elements in the array in advance (but know that they match)
How could you not know the number of inputs or elements but know they match?
You can curry the function and then use one of the solutions proposed here.
For instance, using this technique:
class Acc[T](f: Function1[T, _]) {
private[this] var ff: Any = f
def apply(t: T): this.type = {
ff = ff.asInstanceOf[Function1[T,_]](t)
this
}
def get = ff match {
case _: Function1[_,_] => sys.error("not enough arguments")
case res => res.asInstanceOf[T]
}
}
def test(x1: Int, x2:Int, x3: Int, x4: Int, x5: Int) = {
//Some logic
}
val inputs = Array(1, 2, 3, 4, 5)
inputs.foldLeft(new Acc((test _).curried))((acc, i) => acc(i)).get
Not extremely safe, but it should work
You can use Java reflection (or Scala reflection, but Java's one is sufficient for this). The below is a quick and dirty solution, which assumes you have a class Test which contains exactly one test method:
val m = classOf[Test].
getMethods.find(_.getName == "test").
getOrElse(throw new Exception("No method called test"))
// inputs must be Array[Object], not Array[Int] as in your example
m.invoke(instanceOfTest, inputs)
This is rarely a good idea, however.

Writing tests to verify passing a function as argument in Scala

I have something like this:
def fnA(argA: Int, argB: Int, argC: Int): Seq[Int] = {
tryRequest {
...
}
}
def tryRequest[T](f: => T): T = {
try {
f
} catch {
...
}
}
I'm trying to figure out how to test this with Mockito/ScalaTest. I want to either make sure that 1. my return type is what I expect it to be (Seq[Int] when I call fnA), or 2. that I am passing in the right type to tryRequest when I'm calling it ((Int, Int, Int) => Seq[Int] when I call fnA). I've tried variations of:
exampleInstance.fnA(1, 2, 3)
there was one(exampleInstance).tryRequest(any)
but I always get something like
Argument(s) are different! Wanted:
exampleInstance.tryRequest(
($anonfun$apply$17) <function0>
);
Actual invocation has different arguments:
exampleInstance.tryRequest(
($anonfun$fnA$1) <function0>
);
Any ideas how I can accurately test this? Thanks!
It's not entirely clear what you're passing where - you seem to think you're passing a (Int, Int, Int) => Seq[Int] to tryRequest, but the definition of fnA you give isn't doing that (it's already taken the Int arguments before it calls tryRequest). But going by what you've written rather than the code:
It's generically impossible to compare functions for equality, and that syntax will "really" create an anonymous wrapper (do you really need the laziness of the => T given that you're passing a function in there anyway?), thus the failures. What you can do is confirm that the function that was passed to the inner call has some of the same properties as the function you already passed. I don't know the fancy syntax, but with an ordinary Java testing/mocking library I'd do something like:
val myCaptor = capture[=> ((Int, Int, Int) => Seq[Int])]
expect(exampleInstance.tryRequest(myCaptor.capture()))
exampleInstance.fnA({(a, b, c) => a + b + c})
val functionThatWasPassed = myCaptor.getValue()
assertThat(functionThatWasPassed(3, 4, 5)) isEqualTo 12
assertThat(functionThatWasPassed(-1, 0, 2)) isEqualTo 1