How to get a Long typed production of a Seq[Int] in Scala? - scala

Suppose val s = Seq[Int] and I would like to get the production of all its elements. The value is guaranteed to be greater than Int.MaxValue but less than Long.MaxValue so I hope the value to be a Long type.
It seems I cannot use product/foldLeft/reduceLeft due to the fact Long and Int are different types without any relations; therefore I need to write a for-loop myself. Is there any decent way to achieve this goal?
Note: I'm just asking the possibility to use builtin libraries but still fine with "ugly" code below.
def product(a: Seq[Int]): Long = {
var p = 1L
for (e <- a) p = p * e
p
}

There's no need to mess about with asInstanceOf or your own loop. foldLeft works just fine
val xs = Seq(1,1000000000,1000000)
xs.foldLeft(1L)((a,e) => a*e)
//> res0: Long = 1000000000000000

How about
def product(s: Seq[Int]) = s.map(_.asInstanceOf[Long]).fold(1L)( _ * _ )
In fact, having re-read your question and learnt about the existence of product itself, you could just do:
def product(s: Seq[Int]) = s.map(_.asInstanceOf[Long]).product

Related

How to explain that "Set(someList : _*)" results the same as "Set(someList).flatten"

I found a piece of code I wrote some time ago using _* to create a flattened set from a list of objects.
The real line of code is a bit more complex and as I didn't remember exactly why was that there, took a bit of experimentation to understand the effect, which is actually very simple as seen in the following REPL session:
scala> val someList = List("a","a","b")
someList: List[java.lang.String] = List(a, a, b)
scala> val x = Set(someList: _*)
x: scala.collection.immutable.Set[java.lang.String] = Set(a, b)
scala> val y = Set(someList).flatten
y: scala.collection.immutable.Set[java.lang.String] = Set(a, b)
scala> x == y
res0: Boolean = true
Just as a reference of what happens without flatten:
scala> val z = Set(someList)
z: scala.collection.immutable.Set[List[java.lang.String]] = Set(List(a, a, b))
As I can't remember where did I get that idiom from I'd like to hear about what is actually happening there and if there is any consequence in going for one way or the other (besides the readability impact)
P.S.: Maybe as an effect of the overuse of underscore in Scala language (IMHO), it is kind of difficult to find documentation about some of its use cases, specially if it comes together with a symbol commonly used as a wildcard in most search engines.
_* is for expand this collection as if it was written here literally, so
val x = Set(Seq(1,2,3,4): _*)
is the same as
val x = Set(1,2,3,4)
Whereas, Set(someList) treats someList as a single argument.
To lookup funky symbols, you could use symbolhound

foldLeft early termination in a Stream[Boolean]?

I have a:
val a : Stream[Boolean] = ...
When I foldLeft it as follows
val b = a.foldLeft(false)(_||_)
Will it terminate when it finds the first true value in the stream? If not, how do I make it to?
It would not terminate on the first true. You can use exists instead:
val b = a.exists(identity)
No it won't terminate early. This is easy to illustrate:
val a : Stream[Boolean] = Stream.continually(true)
// won't terminate because the strea
val b = a.foldLeft(false)(_||_)
stew showed that a simple solution to terminate early, in your specific case, is
val b = a.exists(identity).
Even simpler, this is equivalent to:
val b = a.contains(true)
A more general solution which unlike the above is also applicable if you actually need a fold, is to use recursion (note that here I am assuming the stream is non-empty, for simplicity):
def myReduce( s: Stream[Boolean] ): Boolean = s.head || myReduce( s.tail )
val b = myReduce(a)
Now the interesting thing of the recursive solution is how it can be used in a more general use case where you actually need to accumulate the values in some way (which is what fold is for) and still terminate early. Say that you want to add the values of a stream of ints using an add method that will "terminate" early in a way similar to || (in this case, it does not evaluate its right hand side if the left hand side is > 100):
def add(x: Int, y: => Int) = if ( x >= 100 ) x else x + y
val a : Stream[Int] = Stream.range(0, Int.MaxValue)
val b = a.foldLeft(0)(add(_, _))
The last line won't terminate, much like in your example. But you can fix it like this:
def myReduce( s: Stream[Int] ): Int = add( s.head, myReduce( s.tail ) )
val b = myReduce(a)
WARNING: there is a significant downside to this approach though: myReduce here is not tail recursive, meaning that it will blow your stack if iterating over too many elements of the stream.
Yet another solution, which does nto blow the stack, is this:
val b = a.takeWhile(_ <= 100).foldLeft(0)(_ + _)
But I fear I have gone really too far on the off topic side, so I'd better stop now.
You could use takeWhile to extract the prefix of the Stream on which you want to operate and then apply foldLeft to that.

Scalacheck: Generate list corresponding to list of generators

I want to generate a list of integers corresponding to a list of generators in ScalaCheck.
import org.scalacheck._
import Arbitrary.arbitrary
val smallInt = Gen.choose(0,10)
val bigInt = Gen.choose(1000, 1000000)
val zeroOrOneInt = Gen.choose(0, 1)
val smallEvenInt = smallInt suchThat (_ % 2 == 0)
val gens = List(smallInt, bigInt, zeroOrOneInt, smallEvenInt)
//val listGen: Gen[Int] = ??
//println(listGen.sample) //should print something like List(2, 2000, 0, 6)
For the given gens, I would like to create a generator listGen whose valid sample can be List(2, 2000, 0, 6).
Here is my first attempt using tuples.
val gensTuple = (smallInt, bigInt, zeroOrOneInt, smallEvenInt)
val tupleGen = for {
a <- gensTuple._1
b <- gensTuple._2
c <- gensTuple._3
d <- gensTuple._4
} yield (a, b, c, d)
println(tupleGen.sample) // prints Some((1,318091,0,6))
This works, but I don't want to use tuples since the list of generators(gens) is created dynamically
and the size of the list is not fixed. Is there a way to do it with Lists?
I want the use the generator of the list(listGen) in scalacheck forAll property checking.
This looks like a toy problem but this is
the best I could do to create a standalone snippet reproducing the actual issue I am
facing.
How about using the Gen.sequence method? It transforms an Iterable[Gen[T]] into a Gen[C[T]], where C can be List:
def sequence[C[_],T](gs: Iterable[Gen[T]])(implicit b: Buildable[T,C]): Gen[C[T]] =
...
Just use Gen.sequence, but be careful as it will try to return a java.util.ArrayList[T] if you don't fully parameterize it (bug).
Full working example:
def genIntList(): Gen[List[Int]] = {
val gens = List(Gen.chooseNum(1, 2), Gen.chooseNum(3, 4))
Gen.sequence[List[Int], Int](gens)
}
println(genIntList.sample.get) // prints: List(1,4)
EDIT: Please disregard, this doesn't answer the asker's question
I can't comment on posts yet, so I'll have to venture a guess here. I presume the function 'sample' applies to the generators
Any reason why you can't do:
gens map (t=>t.sample)
For a more theoretical answer: the method you want is traverse, which is equivalent to sequence compose map although it might be more efficient. It is of the general form:
def traverse[C[_]: Traverse, F[_]: Applicative, A, B](f: A => F[B], t: C[A]): F[C[B]]
It behaves like map but allows you to carry around some extra Applicative structure during the traversal, sequencing it along the way.

Most concise way to combine sequence elements

Say we have two sequences and we and we want to combine them using some method
val a = Vector(1,2,3)
val b = Vector(4,5,6)
for example addition could be
val c = a zip b map { i => i._1 + i._2 }
or
val c = a zip b map { case (i, j) => i + j }
The repetition in the second part makes me think this should be possible in a single operation. I can't see any built-in method for this. I suppose what I really want is a zip method that skips the creation and extraction of tuples.
Is there a prettier / more concise way in plain Scala, or maybe with Scalaz? If not, how would you write such a method and pimp it onto sequences so I could write something like
val c = a zipmap b (_+_)
There is
(a,b).zipped.map(_ + _)
which is probably close enough to what you want to not bother with an extension. (You can't use it point-free, unfortunately, since the implicits on zipped don't like that.)
Rex's answer is certainly the easier way out for most cases. However, zipped is more limited than zip, so you might stumble upon cases where it won't work.
For those cases, you might try this:
val c = a zip b map (Function tupled (_+_))
Or, alternatively, if you do have a function or method that does what you want, you have this option as well:
def sumFunction = (a: Int, b: Int) => a + b
def sumMethod(a: Int, b: Int) = a + b
val c1 = a zip b map sumFunction.tupled
val c2 = a zip b map (sumMethod _).tupled
Using .tupled won't work in the first case because Scala won't be able to infer the type of the function.

Declaring multiple variables in Scala

I'd like to use val to declare multiple variable like this:
val a = 1, b = 2, c = 3
But for whatever reason, it's a syntax error, so I ended up using either:
val a = 1
val b = 2
val c = 3
or
val a = 1; val b = 2; val c = 3;
I personally find both options overly verbose and kind of ugly.
Is there a better option?
Also, I know Scala is very well thought-out language, so why isn't the val a = 1, b = 2, c = 3 syntax allowed?
The trivial answer is to declare them as tuples:
val (a, b, c) = (1, 2, 3)
What might be interesting here is that this is based on pattern matching. What is actually happens is that you are constructing a tuple, and then, through pattern matching, assigning values to a, b and c.
Let's consider some other pattern matching examples to explore this a bit further:
val DatePattern = """(\d{4})-(\d\d)-(\d\d)""".r
val DatePattern(year, month, day) = "2009-12-30"
val List(rnd1, rnd2, rnd3) = List.fill(3)(scala.util.Random.nextInt(100))
val head :: tail = List.range(1, 10)
object ToInt {
def unapply(s: String) = try {
Some(s.toInt)
} catch {
case _ => None
}
}
val DatePattern(ToInt(year), ToInt(month), ToInt(day)) = "2010-01-01"
Just as a side note, the rnd example, in particular, may be written more simply, and without illustrating pattern matching, as shown below.
val rnd1, rnd2, rnd3 = scala.util.Random.nextInt(100)
Daniel's answer nicely sums up the correct way to do this, as well as why it works. Since he already covered that angle, I'll attempt to answer your broader question (regarding language design)...
Wherever possible, Scala strives to avoid adding language features in favor of handling things through existing mechanisms. For example, Scala doesn't include a break statement. However, it's almost trivial to roll one of your own as a library:
case object BreakException extends RuntimeException
def break = throw BreakException
def breakable(body: =>Unit) = try {
body
} catch {
case BreakException => ()
}
This can be used in the following way:
breakable {
while (true) {
if (atTheEnd) {
break
}
// do something normally
}
}
(note: this is included in the standard library for Scala 2.8)
Multiple assignment syntaxes such as are allowed by languages like Ruby (e.g. x = 1, y = 2, z = 3) fall into the category of "redundant syntax". When Scala already has a feature which enables a particular pattern, it avoids adding a new feature just to handle a special case of that pattern. In this case, Scala already has pattern matching (a general feature) which can be used to handle multiple assignment (by using the tuple trick outlined in other answers). There is no need for it to handle that particular special case in a separate way.
On a slightly different aside, it's worth noting that C's (and thus, Java's) multiple assignment syntax is also a special case of another, more general feature. Consider:
int x = y = z = 1;
This exploits the fact that assignment returns the value assigned in C-derivative languages (as well as the fact that assignment is right-associative). This is not the case in Scala. In Scala, assignment returns Unit. While this does have some annoying drawbacks, it is more theoretically valid as it emphasizes the side-effecting nature of assignment directly in its type.
I'll add one quirk here, because it hit myself and might help others.
When using pattern matching, s.a. in declaring multiple variables, don't use Capital names for the variables. They are treated as names of classes in pattern matching, and it applies here as well.
val (A,B)= (10,20) // won't work
println(A)
Error message does not really tell what's going on:
src/xxx.scala:6: error: not found: value A
val (A,B)= (10,20)
^
src/xxx.scala:6: error: not found: value B
val (A,B)= (10,20)
^
src/xxx.scala:7: error: not found: value A
println(A)
^
I thought `-ticking would solve the issue but for some reason does not seem to (not sure, why not):
val (`A`,`B`)= (10,20)
println(A)
Still the same errors even with that.
Please comment if you know how to use tuple-initialization pattern with capital variable names.
If all your variables are of the same type and take same initial value, you could do this.
val a, b, c: Int = 0;
It seems to work if you declare them in a tuple
scala> val (y, z, e) = (1, 2, 45)
y: Int = 1
z: Int = 2
e: Int = 45
scala> e
res1: Int = 45
Although I would probably go for individual statements. To me this looks clearer:
val y = 1
val z = 2
val e = 45
especially if the variables are meaningfully named.