0

I'm a Scala newbie and have a question about Stream.map(). I want a stream of 12 players. Why can not I do that:

case class Player(number: Int)
Stream.range(1, 12, 1).map[Player](i => new Player(i))

What is the right way to use the map function?
Thanks for your help.

jules
  • 357
  • 1
  • 3
  • 11
  • 1
    As the error message says: wrong number of type parameters. You'd have to write something like `.map[Player, Stream[Player]](...)`. But: 1) Those type ascriptions are unnecessary. 2) You don't need `new` to instantiate case classes, a `.map(Player)` would be sufficient. 3) Why do you want `Stream`? – Andrey Tyukin Apr 07 '19 at 14:08
  • 1
    `Stream.range(1, 12, 1).map(i => Player(i))` - Just let the compiler infer the return type of your _map_. Also, since **Player** is a case class, do not use `new`. Finally, [case classes should be `final`](https://stackoverflow.com/questions/34561614/should-i-use-the-final-modifier-when-declaring-case-classes/34562046) – Luis Miguel Mejía Suárez Apr 07 '19 at 14:08
  • @AndreyTyukin The thing is that with Ctrl+click on `map` IntelliJ jumps to `TraversableOnce.scala` but compiler doesn't accept this `map` with single type parameter. – Dmytro Mitin Apr 07 '19 at 14:28

2 Answers2

2

Try

Stream.range(1, 12, 1).map(i => Player(i))

or

Stream.range(1, 12, 1).map[Player, Stream[Player]](i => Player(i))

or

(Stream.range(1, 12, 1) : TraversableOnce[Int]).map[Player](i => Player(i))
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
2
  1. The method map requires two type arguments (element type and the type of returned collection, which might depend in a non-trivial way on the element type). Both arguments are usually omitted.

  2. You don't need new to instantiate case classes. Indeed, the Player companion object Player can be used as a function from Int to Player.

Applying these two hints gives you:

Stream.range(1, 12).map(Player)

However, it is a bit strange that you are using Stream for a tiny collection with a fixed number of elements. A List or Vector would seem much more appropriate here, so you might even try something like

1 to 12 map Player

If you are wondering why map takes two type parameters, here are few examples:

// return `Iterable` instead of `Stream`
Stream.range(1, 12).map[Player, Iterable[Player]](Player)

// return `Iterable` instead of `Stream` and `Any` instead of `Player`
Stream.range(1, 12).map[Player, Iterable[Any]](Player)

This will produce values with the specified return types (e.g. Iterable[Player] instead of Stream[Player]). Thus, the second type argument can be used to control the return type. Normally, you don't need it, and the appropriate type is returned automatically.

Andrey Tyukin
  • 43,673
  • 4
  • 57
  • 93