我正在尝试为在Scala中保存列表的列表对象实现我自己的通用flatten。 此时我已经
了def myFlatten[T](list: List[List[t]]): List[T] = {
for (xs <- list)
for (x <- xs) yield x
}
我收到一条消息:
找到xs找到单位所需列表。
答案 0 :(得分:23)
def myFlatten[T](list : List[List[T]]) = for(xs <- list; x <- xs) yield x
答案 1 :(得分: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]
的事实是List
是Monad的原因的50%。通常,这称为join
。另外50%来自于您可以在A => B
之间映射函数List[A]
以产生List[B]
。通用名称是Functor map
。 fmap and join on Wikipedia
为类型构造函数M
定义Monad的另一种方法是使用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)
答案 2 :(得分:6)
就个人而言,我喜欢这种风格:
def myFlatten[T](list: List[List[t]]): List[T] = for {
xs <- list
x <- xs
} yield x