Lindon - 6 months ago 39

Scala Question

Here is a minimal example, I can define a function that gives my the next integer via

`def nextInteger(input: Int): Int = input+1`

I can then define a lazy stream of integers as

`lazy val integers: Stream[Int] = 1 #:: integers map(x=>nextInteger(x))`

To my surprise, taking the first element of this stream is 2 and not 1

`scala> integers`

res21: Stream[Int] = Stream(2, ?)

In this simple example I can achieve my desired result using 0 instead of 1 in the definition of integers, but how can one in general set up a stream such that the initial value isn't lost? In my case I am setting up an iterative algorithm and will want to know the initial value.

EDIT:

Furthermore, I've never understood the design choice which makes the following syntax fail:

`scala> (integers take 10 toList) last`

res27: Int = 11

scala> integers take 10 toList last

<console>:24: error: not found: value last

integers take 10 toList last

^

I find wrapping things in brackets cumbersome, is there a shorthand I am not aware of?

Answer

You're probably thinking that `1 #:: integers map(x=>nextInteger(x))`

is parsed as `1 #:: (integers map(x=>nextInteger(x)))`

while it is actually parsed as `(1 #:: integers).map(x=>nextInteger(x))`

. Adding parens fixes your problem:

```
val integers: Stream[Int] = 1 #:: (integers map nextInteger)
```

(Notice that since `nextInteger`

is just a function, you don't need to make a lambda for it, and since `Stream`

is already lazy, making `integers`

lazy is unnecessary)

As to your edit, check out this excellent answer on the matter. In short: no there is no easy way. The thing is that unless you already know the arity of the functions involved, having something like what you suggest work would be hell for the next person reading your code... For example,

```
myList foo bar baz
```

Might be be `myList.foo.bar.baz`

as well as `myList.foo(bar).baz`

and you wouldn't know without checking the definitions of `foo`

, `bar`

, and `baz`

. Scala decides to eliminate this ambiguity - it is always the latter.