type method generic classes scala generics types foreach

scala - method - ¿Cuál es el punto del tipo genérico en foreach?



scala type bounds (2)

Al no ser Martin Odersky, solo puedo adivinar :-) Viendo el Scaladoc de foreach , veo esto:

/** Applies a function `f` to all elements of this $coll. * * @param f the function that is applied for its side-effect to every element. * The result of function `f` is discarded. * * @tparam U the type parameter describing the result of function `f`. * This result will always be ignored. Typically `U` is `Unit`, * but this is not necessary. * * @usecase def foreach(f: A => Unit): Unit */

Así que el tipo de retorno de f no importa y su resultado siempre se descarta. Esto, para mí, sugiere que usar un parámetro de tipo genérico aquí para marcar el tipo de retorno es solo una sutileza de la documentación, diciendo que "el tipo de retorno puede ser cualquier cosa, realmente cualquier cosa, que te guste". Mientras que un tipo de retorno de Any puede sugerir a (algunos) lectores algún tipo de limitación a los tipos de función aplicables aquí.

Otro aspecto es que Scala fue diseñado muy conscientemente para ser genérico desde cero. Entonces, para mí, el uso de un parámetro de tipo genérico aquí es coherente con la filosofía general del lenguaje, mientras que el uso de Any (aunque sea técnicamente utilizable) sería un enfoque definitivamente no genérico que estaría en desacuerdo con el resto del lenguaje.

Tengo curiosidad: ¿cuál es el punto del tipo genérico U en la declaración del método foreach de Traversable ?

def foreach[U](f: A => U): Unit

Dado que el tipo de retorno de Function1 es covariante, ¿por qué no puede ser simplemente:

def foreach(f: A => Any): Unit

?


Tal vez para permitirle heredar de un Traversable , y hacer uso del valor de retorno U de f: A => U ?

trait TraversableWithHandler[+A, E <: Option[Throwable]] extends Traversable[A] { override def foreach[U](f: A => U): Unit def handleError(t: E) }

Por ejemplo, en jQuery , la devolución de false desde adentro foreach es equivalente a break , cualquier valor diferente es un continue .

Caso de uso

breakable { List(1,2,3).foreach(_ match { case 1 => println("ok") case 2 => println("Sort of, soft interrupt?") return false case 3 => break }) }

Debido a que el siguiente código (paralelo), nunca se rompe (¿la solución de lanzamiento sin pila parece no ideal en este caso?):

import scala.util.control.Breaks._ breakable { (0 to 100).toList.par.foreach(_ match { case n if (n <= 50) => println("#" * 100) try { break } catch { case t: Throwable => println("" + t); break } case n if (n > 50) => println("" + n) case _ => "ok" }) }