molto vicino! Ecco uno che funziona:
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 utilizzare il built-in 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)
E 'istruttivo vedere come scrivere questa funzione senza lo zucchero sintattico 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)
UPDATE
proposito, il fatto che List[List[T]]
può essere appiattito per List[T]
è del 50% del motivo che List
è una Monade. Generalmente, questo è noto come join
. L'altro 50% deriva dal fatto che è possibile mappare una funzione A => B
su uno List[A]
in modo che risulti un List[B]
. Il nome generale per questo è un Functor map
. fmap and join on Wikipedia.
Un diverso modo di definire un Monade per tipo di costruzione è M
con un'operazione pure
, che assume un valore di tipo A
, e restituisce una M[A]
; e un'operazione bind
che accetta uno M[A]
, una funzione A => M[B]
e restituisce M[B]
. Per le liste, pure
== List(_)
, e bind
= (l: List[A], f: (A => List[B])) => l.flatMap(f)