Muy cerca! Aquí hay una que funciona:
scala> def myFlatten[T](list: List[List[T]]): List[T] = for (xs <- list; x <- xs) yield x
myFlatten: [T](list: List[List[T]])List[T]
O utilizar el incorporado en flatten
scala> List(List(1, 2), List(3)).flatten
res0: List[Int] = List(1, 2, 3)
scala> List(Set(1, 2), Set(3)).flatten
res1: List[Int] = List(1, 2, 3)
Es instructivo ver cómo escribir esta función sin el azúcar sintáctica for
.
scala> def myFlatten[T](list: List[List[T]]): List[T] = list flatMap identity
myFlatten: [T](list: List[List[T]])List[T]
scala> myFlatten(List(List(1, 2), List(3)))
res3: List[Int] = List(1, 2, 3)
ACTUALIZACIÓN
Por cierto, el hecho de que List[List[T]]
puede aplanarse a List[T]
es 50% de la razón de que List
es una Mónada. En general, esto se conoce como join
. El otro 50% proviene del hecho de que puede asignar una función A => B
a través de List[A]
para generar un List[B]
. El nombre general para esto es Functor map
. fmap and join on Wikipedia.
Una forma diferente de la definición de una Mónada para el tipo constructor M
es con una operación de pure
, que toma un valor de tipo A
, y devuelve un M[A]
; y una operación bind
que toma un M[A]
, una función A => M[B]
, y da como resultado M[B]
. Por Listas, pure
== List(_)
y bind
= (l: List[A], f: (A => List[B])) => l.flatMap(f)