2010-02-20 2 views
16

Я пытаюсь реализовать свою собственную общую сглаживание для объектов списка, которые хранят списки в Scala. На данный момент у меня естьКак перечислить список списков в Scala?

def myFlatten[T](list: List[List[t]]): List[T] = { 
    for (xs <- list) 
     for (x <- xs) yield x 
} 

я получаю сообщение:

для хз найти требуемый блок списка.

ответ

23
def myFlatten[T](list : List[List[T]]) = for(xs <- list; x <- xs) yield x 
12

Очень близко! Вот один, который работает:

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] 

Или использовать встроенный 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) 

Поучительно посмотреть, как написать эту функцию без 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) 

ОБНОВЛЕНИЕ

Кстати, тот факт, что List[List[T]] может быть уплощен к List[T] составляет 50% от той причине, что List является Монада. Как правило, это известно как join. Остальные 50% исходят из того факта, что вы можете сопоставить функцию A => B через List[A], чтобы получить List[B]. Общее имя для этого - Functor map. fmap and join on Wikipedia.

Другой способ определения Монадой для типа конструктора M это с pure операции, которая принимает значение типа A, и возвращает M[A]; и операцию bind, которая принимает M[A], функцию A => M[B] и приводит к M[B]. Для списков, pure == List(_) и bind = (l: List[A], f: (A => List[B])) => l.flatMap(f)

6

Лично мне нравится этот стиль:

def myFlatten[T](list: List[List[t]]): List[T] = for { 
    xs <- list 
    x <- xs 
} yield x 
Смежные вопросы