2013-10-16 4 views
2

Après avoir lu cet excellent answer sur les expressions, j'ai essayé de convertir mon flatMap en for-expression.flatMap versus pour l'expression

val results: List[String] = foo() 
def getId: List[String] = List((json \ "_id").asOpt[String].getOrElse("")) 
val xs: List[String] = results.flatMap(x => getId(Json.parse(x))) 

Ensuite, la for-expression.

val results: List[String] = foo() 
def getId: List[String] = List((json \ "_id").asOpt[String].getOrElse("")) 
val xs: List[String] = for { 
    r <- result 
    getId(Json.parse(r)) 
} 

Je reçois une erreur de compilation que <- était attendu sur la ligne getId(...), mais trouvé }.

Qu'est-ce qui ne va pas avec my for expression?

Répondre

2

votre entreprise à la compréhension doit lier le résultat de getId à un nom, et yield que:

val xs: List[String] = for { 
    r <- result 
    x <- getId(Json.parse(r)) 
} yield x 

Chaque ligne dans la for-compréhension doit soit lier le résultat d'un calcul monadique à un nom en utilisant

x <- expr 

// or, `_ <- expr` to run `expr` purely for its effects and ignore the result 

ou il doit être une tâche simple comme

x = expr 

Depuis getId(Json.parse(r)) seul ne fait ni l'un ni l'autre, ceci est invalide.

+0

ah, donc «rendement» est toujours nécessaire? Dans le cas de la carte à for-expression, le rendement retournera une liste [...]. Mais pour un flatMap à for-expression, yield retournera une List [List [...]]? –

+1

'yield' est requis si vous voulez obtenir une valeur (par opposition aux effets secondaires.) Je ne suis pas sûr d'où vous avez' List [List [...]] 'from. –