Question

Je suis un débutant Scala relative et aimerait avoir des conseils sur la façon de procéder à une mise en œuvre qui semble comme il peut se faire soit avec une fonction de retour Option ou avec fonction partielle. J'ai lu tous les messages connexes que je pouvais trouver (voir en bas de la question), mais ceux-ci semblent impliquer les détails techniques de l'utilisation ou la conversion d'un fonction partielle à l'autre; Je cherche une réponse du type « si les circonstances sont X, Y, Z, puis utilisez un autre B, mais aussi considérer C ».

Mon exemple cas d'utilisation est une recherche de chemin entre les sites en utilisant une bibliothèque de trouveurs de chemin. Dites les emplacements sont de type L, un chemin était de type P et le résultat de recherche de trajectoire souhaitée serait un Iterable[P]. Le résultat de la recherche de patch doit être assemblé en demandant à tous les trouveurs de chemin (quelque chose comme google maps ceux-ci pourraient être vélos, voitures, Marche, métro, etc.) pour leurs suggestions de chemin, ce qui peut ou ne peut pas être défini pour un début particulier / emplacement de fin pair.

Il semble y avoir deux façons d'aller à ce sujet:

(a) définir un viseur de chemin comme f: (L,L) => Option[P] puis obtenir le résultat par quelque chose comme finders.map( _.apply(l1,l2) ).filter( _.isDefined ).map( _.get )

(b) définir un détecteur de trajet comme f: PartialFunction[(L,L),P] and then get the result via something likefinders.filter (_.isDefined ((L1, L2))) .map (_.apply ((L1, L2))) `

Il semble que l'aide d'une fonction de retour Option[P] serait d'éviter une double évaluation des résultats, donc pour un calcul coûteux cela peut être préférable à moins que l'un met en cache les résultats. Il semble aussi que l'utilisation d'une Option peut avoir une signature d'entrée arbitraire, alors que PartialFunction attend un seul argument. Mais je suis particulièrement intéressé à entendre parler de quelqu'un ayant une expérience pratique sur les considérations moins immédiates, plus « grande image », comme l'interaction avec la bibliothèque Scala. Plût à l'aide d'un PartialFunction ont des avantages significatifs dans la mise à disposition de certaines méthodes de l'API collections qui pourraient payer par d'autres moyens? Would tel code généralement plus concis?

Questions connexes mais différentes:

Était-ce utile?

La solution

Il se sent comme Option pourrait convenir mieux votre cas d'utilisation.

Mon interprétation est que les fonctions partielles fonctionnent bien être combinés sur des plages d'entrée. Donc, si f est défini sur (SanDiego,Irvine) et g est défini sur (Paris,London) alors vous pouvez obtenir une fonction qui est définie sur la (SanDiego,Irvine) d'entrée combiné et (Paris,London) en faisant f orElse g.

Mais dans votre cas, il semble, les choses se passent pour un emplacement de (l1,l2) donné tuple puis vous faites un peu de travail ...

Si vous vous retrouvez à écrire beaucoup de {case (L,M) => ... case (P,Q) => ...} alors il peut être le signe que des fonctions partielles sont un meilleur ajustement.

Sinon options fonctionnent bien avec le reste des collections et peuvent être utilisés comme celui-ci au lieu de votre (a) proposition:

val processedPaths = for {
  f <- finders
  p <- f(l1, l2)
} yield process(p)

Dans le p pour la compréhension est levée dans un Traversable, de sorte que vous n'avez même pas appeler filter, isDefined ou get sauter les trouveurs sans résultats.

Autres conseils

Il est pas tout à fait bien connu, mais depuis Scala 2.8 a une méthode collect définie sur les collections de it. collect est similaire à filter, mais prend une fonction partielle et a la sémantique que vous décrivez.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top