是否有Scala身份功能?


68

如果我有类似a的东西List[Option[A]]并且想要将其转换为a List[A],则标准方法是使用flatMap

scala> val l = List(Some("Hello"), None, Some("World"))
l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World))

scala> l.flatMap( o => o)
res0: List[java.lang.String] = List(Hello, World)

现在o => o只是一个身份功能。我本以为可以采取一些措施:

l.flatMap(Identity) //return a List[String]

但是,由于您无法生成一个,所以我无法执行此操作object。我尝试了几件事无济于事。有人有这样的工作吗?


3
我认为,{_}应该等同于{x => x}同样{_ + 3}等同于{x => x+3}。谁能评论为什么不是这样?
兰德尔·惠特曼

Answers:


64

Predef中有一个标识函数

l flatMap identity[Option[String]]

> List[String] = List(Hello, World)

我认为a表示更好。

for(x <- l; y <- x) yield y

编辑:

我试图弄清楚为什么需要类型参数(Option [String])。问题似乎是从Option [T]到Iterable [T]的类型转换。

如果将身份函数定义为:

l.flatMap( x => Option.option2Iterable(identity(x)))

type参数可以省略。


类型推断者为何无法弄清楚类型本身?为什么不起作用l.flatMap(identity): List[String]
oxbow_lakes 2009年

我以为推理者可以解决这个问题。我不知道。我将添加一个问题。:-)
Thomas Jung

1
@oxbow_lakes-参见编辑。它与隐式类型转换有关。
Thomas Jung

@托马斯-谢谢。关于身份/选项/可迭代事物的耻辱似乎是这可能被使用的主要场所之一。不幸的是,具有身份的可读性比没有身份的可读性差
oxbow_lakes

该解决方案似乎在scala 2.9.1中不起作用。l flatMap identity[Option[String]] <console>:9: error: polymorphic expression cannot be instantiated to expected type; found : Option[String] => Option[String] required: Option[java.lang.String] => scala.collection.GenTraversableOnce[?] l flatMap identity[Option[String]] ^
devth 2012年

22

FWIW,在Scala 2.8上,您只需调用flatten它即可。Thomas在Scala 2.7中涵盖了大部分内容。他只错过了使用该身份的另一种方法:

l.flatMap[String](identity)

但是,它不能与运算符表示法一起使用(似乎运算符表示法不接受类型参数,这是一个很好的认识)。

您也可以调用flattenScala 2.7(List至少在上),但是如果没有类型,它将无法执行任何操作。但是,这可行:

l.flatten[String]

3

您可以给类型推断器一些帮助:

scala> val l = List(Some("Hello"), None, Some("World"))
l: List[Option[java.lang.String]] = List(Some(Hello), None, Some(World))

scala> l.flatten[String]
res0: List[String] = List(Hello, World)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.