Я пытаюсь реализовать свой собственный дженерик, сглаживаются для объектов списка, которые содержат списки в Scala. В этой точке я имею
def myFlatten[T](list: List[List[t]]): List[T] = {
for (xs <- list)
for (x <- xs) yield x
}
Я получаю сообщение:
поскольку xs нашел Единицу требуемым списком.
def myFlatten[T](list : List[List[T]]) = for(xs <- list; x <- xs) yield x
Очень близко! Вот тот, который работает:
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)
Поучительно посмотреть, как написать эту функцию без синтаксического сахара для
.
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
- Монада. Обычно это называется соединение
. Остальные 50% связаны с тем, что вы можете отобразить функцию A => B
в List [A]
, чтобы получить List [B]
. Общее название для этого - Functor map
. fmap и присоединяйтесь к Википедии .
Другой способ определения монады для конструктора типов M
- это чистая
операция, которая принимает значение типа A
и возвращает M [A]
; и операция связывания
, которая принимает M [A]
, функцию A => M [B]
и приводит к M [B]
. Для списков pure
== List (_)
и bind
= (l: List [A], f: (A => List) [B])) => l.flatMap (f)
Лично мне нравится этот стиль:
def myFlatten[T](list: List[List[t]]): List[T] = for {
xs <- list
x <- xs
} yield x