Existe uma função de identidade do Scala?
-
22-09-2019 - |
Pergunta
Se eu tenho algo como um List[Option[A]]
e eu quero converter isso em um List[A]
, a maneira padrão é usar 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)
Agora o => o
é apenas uma função de identidade. Eu teria pensado que haveria uma maneira de fazer:
l.flatMap(Identity) //return a List[String]
No entanto, não consigo fazer isso funcionar, pois você não pode gerar um object
. Eu tentei algumas coisas sem sucesso; Alguém tem algo assim para funcionar?
Solução
Há uma identidade função em predef.
l flatMap identity[Option[String]]
> List[String] = List(Hello, World)
A para a expresso é melhor, suponho:
for(x <- l; y <- x) yield y
Editar:
Tentei descobrir por que o parâmetro de tipo (opção [string]) é necessário. O problema parece ser a conversão do tipo da opção [t] para iterable [t].
Se você definir a função de identidade como:
l.flatMap( x => Option.option2Iterable(identity(x)))
o parâmetro de tipo pode ser omitido.
Outras dicas
Fwiw, no scala 2.8 você apenas liga flatten
nele. Thomas Ele abordou principalmente o Scala 2.7. Ele só perdeu uma maneira alternativa de usar essa identidade:
l.flatMap[String](identity)
No entanto, não funcionará com a notação do operador (parece que a notação do operador não aceita parâmetros de tipo, o que é bom saber).
Você pode também ligar flatten
em Scala 2.7 (em um List
, pelo menos), mas não será capaz de fazer nada sem um tipo. No entanto, isso funciona:
l.flatten[String]
Você pode apenas dar uma ajudinha para o tipo Inferencer:
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)