Porque las comprensiones se convierten en llamadas al método map
o flatMap
. Por ejemplo este:
for(x <- List(1) ; y <- List(1,2,3)) yield (x,y)
se convierte en eso:
List(1).flatMap(x => List(1,2,3).map(y => (x,y)))
Por lo tanto, el primer valor de bucle (en este caso List(1)
) recibirá la flatMap
llamada al método. Dado que flatMap
en a List
devuelve otro List
, el resultado de la comprensión será, por supuesto, a List
. (Esto era nuevo para mí: porque las comprensiones no siempre resultan en flujos, ni siquiera necesariamente en Seq
s).
Ahora, eche un vistazo a cómo flatMap
se declara en Option
:
def flatMap [B] (f: (A) ⇒ Option[B]) : Option[B]
Mantén esto en mente. Veamos cómo el error de comprensión (el que tiene Some(1)
) se convierte en una secuencia de llamadas de mapa:
Some(1).flatMap(x => List(1,2,3).map(y => (x, y)))
Ahora, es fácil ver que el parámetro de la flatMap
llamada es algo que devuelve un List
, pero no un Option
, como se requiere.
Para solucionar el problema, puede hacer lo siguiente:
for(x <- Some(1).toSeq ; y <- List(1,2,3)) yield (x, y)
Eso se compila muy bien. Vale la pena señalar que Option
no es un subtipo de Seq
, como a menudo se supone.