2011-12-01 2 views
6

Je suis un débutant de Scala relatif et aimerais quelques conseils sur la façon de procéder pour une implémentation qui semble pouvoir être faite avec une fonction retournant Option ou avec PartialFunction. J'ai lu tous les articles connexes que j'ai pu trouver (voir le bas de la question), mais ceux-ci semblent impliquer les détails techniques de l'utilisation de PartialFunction ou de la conversion de l'un à l'autre; Je cherche une réponse du type "si les circonstances sont X, Y, Z, alors employez A d'autre B, mais considérons aussi C".Scala: sélection de la fonction retournant l'option par rapport à la fonction partielle

Mon exemple d'utilisation est une recherche de chemin entre les emplacements à l'aide d'une bibliothèque de détecteurs de chemin. Dites que les emplacements sont de type L, un chemin était de type P et le résultat de recherche de chemin souhaité serait Iterable[P]. Le résultat de recherche de patch doit être assemblé en demandant à tous les localisateurs de chemin (dans quelque chose comme Google maps, ils peuvent être Bicycle, Car, Walk, Subway, etc.) pour leurs suggestions de chemin, qui peuvent ou non être définies pour un départ particulier. paire d'emplacements de fin.

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éfinissent un détecteur de chemin comme f: PartialFunction[(L,L),P] and then get the result via something like finders.filter (_.isDefined ((l1, l2))) .map (_.apply ((l1, l2))) `

Il semble que l'utilisation d'une fonction renvoyant Option[P] évite une double évaluation des résultats, donc pour un calcul coûteux, cela peut être préférable à moins de mettre en cache les résultats. Il semble également que l'utilisation de Option permet d'avoir une signature d'entrée arbitraire, alors que PartialFunction attend un seul argument. Mais je suis particulièrement intéressé d'entendre quelqu'un avec une expérience pratique sur des considérations moins immédiates, plus «globales», telles que l'interaction avec la bibliothèque Scala. Est-ce que l'utilisation d'un PartialFunction aurait des avantages significatifs à rendre disponibles certaines méthodes de l'API des collections qui pourraient être payantes d'autres façons? Un tel code serait-il généralement plus concis?

des questions connexes mais différentes:

Répondre

3

sentir s comme Option pourrait mieux s'adapter à votre cas d'utilisation. Mon interprétation est que les fonctions partielles fonctionnent bien pour être combinées 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 l'entrée combinéeet (Paris,London) en faisant f orElse g.

Mais dans votre cas, il semble, les choses arrivent pour une donnée (l1,l2) tuple emplacement, 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 peut être utilisé comme celui-ci au lieu de votre (a) proposition:

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

Au sein de la pour la compréhension p est levée dans un Traversable, de sorte que vous n » t même besoin d'appeler filter, isDefined ou get pour sauter les trouveurs sans résultats.

3

Ce n'est pas si bien connu, mais depuis 2.8 Scala a une méthode collect définie sur ses collections. collect est similaire à filter, mais prend une fonction partielle et a la sémantique que vous décrivez.

Questions connexes