How should I interpret the signatures like "fill[A](n: Int)(elem: ⇒ A)"? - scala

The scaladoc of Vector#fill looks like:
def fill[A](n: Int)(elem: ⇒ A): Vector[A]
n the number of elements contained in the collection.
elem the element computation
returns A collection that contains the results of n evaluations of elem.
But this is how I invoke it:
Vector.fill[Boolean](5)(true)
Where is the elem? What does it mean?

elems signature in fill method (=> A) means a by-name parameter. It's different from simple by-value parametes (like n: Int in your example) in that there are not computed when the method is called, but when they are referenced in the method body.
So method fill means that it takes the number of elements in the resulting Vector and fills it with elems of type A, by-name is used because you can fill vector, for ex. with object, and if you are using by-value parameters, then the resulting vector would contain equal object, but with by-value parameter it will paste new object with each cycle.
Implementation:
def fill[A](n: Int)(elem: => A): CC[A] = {
val b = newBuilder[A]
b.sizeHint(n)
var i = 0
while (i < n) {
b += elem // compute elem and add to the collection
i += 1
}
b.result
}

elem is a function that , when invoked once will produce an instance of type "A" in this case Boolean. So in your case function "true" is invoked 5 times and it returns "true" each time.
"elem" is of type "method which returns an A when called"
also the ()() notation in giving parameters allows you to only give part of the parameters first and then pass the partially "filled" function on. called currying.

Related

How does this Scala function work?

def flatMap[A,B](f: Rand[A])(g: A => Rand[B]): Rand[B] =rng => {
val (a, r1) = f(rng)
g(a)(r1)
}
I am confused by g(a)(r1) because g is supposed to take only one argument, so why r1?
I don't exactly know the Rand[A] structure, so this is partially guessing. What you are returning in this function is a Rand[B] and when you implement the function you start of with defining an argument rng of an anonymous function. This tells me that Rand is probably some kind of function itself.
In the second line (val (a, r1) = f(rng)) you apply the value rng to the instance f: Rand[A]. In the resulting tuple, a has type A.
Note with this that f(rng) is equal to explicitly calling apply: f.apply(rng).
You can use the value a to get a Rand[B] by applying this value to the function g. So, val rb: Rand[B] = g(a) (or g.apply(a)).
Now, you don't want to return an instance of Rand[B] in this anonymous function! Instead you need to apply the previous result r1 to this instance rb. So, you get rb(r1) or rb.apply(r1). Substituting rb with g(a) or g.apply(a) gives you g(a)(r1) or g.apply(a).apply(r1).
To summarize, as you said, g is supposed to only take one argument, which results in an instance of Rand[B], but that is not the expected return type here. You need to apply the result of the previous computation to this new computation to get the expected result.

Difference between f(a,b) and f(a)(b) in Scala

I am very very new to Scala. I am reading a book called functional programming in scala by Paul Chiusano and Rúnar Bjarnason. So far I am finding it interesting. I see a solution for curry and uncurry
def curry[A,B,C](f: (A, B) => C): A => (B => C)= {
a => b => f(a,b)
}
def uncurry[A,B,C](f: A => B => C): (A, B) => C = {
(a,b) => f(a)(b)
}
In Curry I understand f(a,b) which results in value of type C but in uncurry I do not understand f(a)(b). Can anyone please tell me how to read f(a)(b) or how is this resulting to a type of C or please refer me some online material that can explain this to me?
Thanks for your help.
Basically the return type of f(a) is a function of type B => C lets call this result g.
If you then call g(b) you obtain a value of type C.
f(a)(b) can be expanded to f.apply(a).apply(b)
In the uncurry method you take a so-called "curried" function, meaning that instead of having a function that evaluates n arguments, you have n functions evaluating one argument, each returning a new function until you evaluate the final one.
Currying without a specific support from the language mean you have to do something like this:
// curriedSum is a function that takes an integer,
// which returns a function that takes an integer
// and returns the sum of the two
def curriedSum(a: Int): Int => Int =
b => a + b
Scala however provides further support for currying, allowing you to write this:
def curriedSum(a: Int)(b: Int): Int = a + b
In both cases, you can partially apply curriedSum, getting a function that takes an integer and sums it to the number you passed in originally, like this:
val sumTwo: Int => Int = curriedSum(2)
val four = sumTwo(2) // four equals 4
Let's go back to your case: as we mentioned, uncurry takes a curried function and turns it into a regular function, meaning that
f(a)(b)
can read as: "apply parameter a to the function f, then take the resulting function and apply the parameter b to it".
In case if somebody is looking for an explanation. This link explains it better
def add(x:Int, y:Int) = x + y
add(1, 2) // 3
add(7, 3) // 10
After currying
def add(x:Int) = (y:Int) => x + y
add(1)(2) // 3
add(7)(3) // 10
In the first sample, the add method takes two parameters and returns the result of adding the two. The second sample redefines the add method so that it takes only a single Int as a parameter and returns a functional (closure) as a result. Our driver code then calls this functional, passing the second “parameter”. This functional computes the value and returns the final result.

A variable used in its own definition?

An infinite stream:
val ones: Stream[Int] = Stream.cons(1, ones)
How is it possible for a value to be used in its own declaration? It seems this should produce a compiler error, yet it works.
It's not always a recursive definition. This actually works and produces 1:
val a : Int = a + 1
println(a)
variable a is created when you type val a: Int, so you can use it in the definition. Int is initialized to 0 by default. A class will be null.
As #Chris pointed out, Stream accepts => Stream[A] so a bit another rules are applied, but I wanted to explain general case. The idea is still the same, but the variable is passed by-name, so this makes the computation recursive. Given that it is passed by name, it is executed lazily. Stream computes each element one-by-one, so it calls ones each time it needs next element, resulting in the same element being produces once again. This works:
val ones: Stream[Int] = Stream.cons(1, ones)
println((ones take 10).toList) // List(1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
Though you can make infinite stream easier: Stream.continually(1) Update As #SethTisue pointed out in the comments Stream.continually and Stream.cons are two completely different approaches, with very different results, because cons takes A when continually takes =>A, which means that continually recomputes each time the element and stores it in the memory, when cons can avoid storing it n times unless you convert it to the other structure like List. You should use continually only if you need to generate different values. See #SethTisue comment for details and examples.
But notice that you are required to specify the type, the same as with recursive functions.
And you can make the first example recursive:
lazy val b: Int = b + 1
println(b)
This will stackoverflow.
Look at the signature of Stream.cons.apply:
apply[A](hd: A, tl: ⇒ Stream[A]): Cons[A]
The ⇒ on the second parameter indicates that it has call-by-name semantics. Therefore your expression Stream.cons(1, ones) is not strictly evaluated; the argument ones does not need to be computed prior to being passed as an argument for tl.
The reason this does not produce a compiler error is because both Stream.cons and Cons are non-strict and lazily evaluate their second parameter.
ones can be used in it's own definition because the object cons has an apply method defined like this:
/** A stream consisting of a given first element and remaining elements
* #param hd The first element of the result stream
* #param tl The remaining elements of the result stream
*/
def apply[A](hd: A, tl: => Stream[A]) = new Cons(hd, tl)
And Cons is defined like this:
final class Cons[+A](hd: A, tl: => Stream[A]) extends Stream[A]
Notice that it's second parameter tl is passed by name (=> Stream[A]) rather than by value. In other words, the parameter tl is not evaluated until it is used in the function.
One advantage to using this technique is that you can compose complex expressions that may be only partially evaluated.

Partial Functions in Scala

I just wanted to clarify something about partially defined functions in Scala. I looked at the docs and it said the type of a partial function is PartialFunction[A,B], and I can define a partial function such as
val f: PartialFunction[Any, Int] = {...}
I was wondering, for the types A and B, is A a parameter, and B a return type? If I have multiple accepted types, do I use orElse to chain partial functions together?
In the set theoretic view of a function, if a function can map every value in the domain to a value in the range, we say that this function is a total function. There can be situations where a function cannot map some element(s) in the domain to the range; such functions are called partial functions.
Taking the example from the Scala docs for partial functions:
val isEven: PartialFunction[Int, String] = {
case x if x % 2 == 0 => x+" is even"
}
Here a partial function is defined since it is defined to only map an even integer to a string. So the input to the partial function is an integer and the output is a string.
val isOdd: PartialFunction[Int, String] = {
case x if x % 2 == 1 => x+" is odd"
}
isOdd is another partial function similarly defined as isEven but for odd numbers. Again, the input to the partial function is an integer and the output is a string.
If you have a list of numbers such as:
List(1,2,3,4,5)
and apply the isEven partial function on this list you will get as output
List(2 is even, 4 is even)
Notice that not all the elements in the original list have been mapped by the partial function. However, there may be situations where you want to apply another function in those cases where a partial function cannot map an element from the domain to the range. In this case we use orElse:
val numbers = sample map (isEven orElse isOdd)
And now you will get as output:
List(1 is odd, 2 is even, 3 is odd, 4 is even, 5 is odd)
If you are looking to set up a partial function that, in effect, takes multiple parameters, define the partial function over a tuple of the parameters you'll be feeding into it, eg:
val multiArgPartial: PartialFunction[(String, Long, Foo), Int] = {
case ("OK", _, Foo("bar", _)) => 0 // Use underscore to accept any value for a given parameter
}
and, of course, make sure you pass arguments to it as tuples.
In addition to other answers, if by "multiple accepted types" you mean that you want the same function accept e.g. String, Int and Boolean (and no other types), this is called "union types" and isn't supported in Scala currently (but is planned for the future, based on Dotty). The alternatives are:
Use the least common supertype (Any for the above case). This is what orElse chains will do.
Use a type like Either[String, Either[Int, Boolean]]. This is fine if you have two types, but becomes ugly quickly.
Encode union types as negation of intersection types.

How to invoke a method taking String * with elements of Array[String]

Suppose I have a method
def f(s:String *) = s.foreach( x => println(x) )
Now I have an array:
val a = Array("1", "2", "3")
How do I invoke f with elements of a as parameters?
EDIT:
So given a, I want to do the following:
f(a(0), a(1), a(2)) // f("1", "2", "3")
There is an operator for that:
f(a: _*)
This operation is defined in chapter 4.6.2 Repeated Parameters of The Scala Language Specification Version 2.9 and further explained in 6.6 Function Applications:
The last argument in an application may be marked as a sequence argument, e.g.
e : _*. Such an argument must correspond to a repeated parameter (§4.6.2) of type
S * [...]. Furthermore, the type of e must conform to scala.Seq[T], for some type T which conforms to S. In this
case, the argument list is transformed by replacing the sequence e with its elements.
BTW your f function can be simplified:
def f(s:String *) = s foreach println
Or better (equals sign is discouraged as it suggests that the method actually returns something, however it "only" return Unit):
def f(s:String *) {s foreach println}