So when creating a foreach method, or a foreach like method in ones own code, of which I have quite a number, what is the current recommended signature?
def foreach[U](f: Element => U): Unit //or
def foreach(f: Element => Unit): Unit
The standard library obviously uses the former. But that often means adding the Unit value “()” at the end of implementations to avoid a warning. Is the U parameter still necessary?
No, Element => Nothing is the subtype of all functions that receive an Element, as such no function would be valid, because you can not pass a super type when a subtype is expected.
Actually that code would also work if foreach accepted only Int => Unit functions. It’s only a “problem” when you have an actual function value.
scala> case class Foo(a: Int) { def foreach(f: Int => Unit): Unit = f(a) }
class Foo
scala> var acc = 0
| def addAndGetPrevious(x: Int): Int = {
| val previous = acc
| acc += x
| previous
| }
var acc: Int = 0
def addAndGetPrevious(x: Int): Int
scala> Foo(42).foreach(addAndGetPrevious)
scala> acc
val res11: Int = 42
scala> val f = addAndGetPrevious _
val f: Int => Int = $Lambda$6412/1491193970@558e51a4
scala> Foo(42).foreach(f)
^
error: type mismatch;
found : Int => Int
required: Int => Unit
Which again goes to show what a nice toolbox cats is:
scala> import cats.implicits._
import cats.implicits._
scala> Foo(42).foreach(f.void)
scala> acc
val res14: Int = 84