2017-09-17 12 views
1

j'ai écrit une combinaison fonction carte et trouver qui applique une fonction à un Iterable et renvoie le premier résultat cartographié pour lequel un prédicat est vrai:erreur d'inférence de type Scala

implicit class EnhancedIterable[A, B[X] <: Iterable[X]](it: B[A]) { 

    def mapAndFind[B](f: A => B, p: B => Boolean): Option[B] = { 
    var result: Option[B] = None 
    for (value <- it if result.isEmpty) { 
     val r = f(value) 
     if (p(r)) 
     result = Some(r) 
    } 
    result 
    } 

} 

Le problème est que je frappe un erreur de compilation lorsque je tente d'utiliser la fonction comme prévu:

val names = Seq("Jose", "Chris", "Carlos", "Stephan") 

names.mapAndFind(
    _.length, 
    _ > 5 // Error 
) 

type mismatch, attendu: (NotInferedB) => Boolean, réelle: (Rien) => Tous

Si j'utilise un indice de type si les choses compilent bien:

names.mapAndFind(
    _.length, 
    (len: Int) => len > 5 
) 

Pourquoi le type B ne déduit pas qu'il en Int de f?

Répondre

1

L'inférence de type dans Scala circule entre les listes de paramètres, pas à l'intérieur de celles-ci.

Vous pouvez écrire:

implicit class EnhancedIterable[A, B[X] <: Iterable[X]](it: B[A]) { 
    def mapAndFind[B](f: A => B)(p: B => Boolean): Option[B] = { 
    var result: Option[B] = None 
    for (value <- it if result.isEmpty) { 
     val r = f(value) 
     if (p(r)) result = Some(r) 
    } 
    result 
    } 
} 

Et puis:

val names = Seq("Jose", "Chris", "Carlos", "Stephan") 
names.mapAndFind(_.length)(_ > 5) 

rendements:

Some(6) 
+1

est parfaitement logique. Merci d'avoir répondu! –