2011-12-01 9 views
6

Soy un principiante relativo de Scala y me gustaría obtener algunos consejos sobre cómo proceder en una implementación que parece que se puede hacer con una función que devuelve Option o con PartialFunction. He leído todas las publicaciones relacionadas que pude encontrar (ver la parte inferior de la pregunta), pero parece que implican los detalles técnicos del uso de PartialFunction o la conversión de una a la otra; Estoy buscando una respuesta del tipo "si las circunstancias son X, Y, Z, luego uso A más B, pero también considero C".Scala: seleccionando la función return Option versus PartialFunction

Mi ejemplo de caso de uso es una búsqueda de ruta entre ubicaciones usando una biblioteca de buscadores de ruta. Supongamos que las ubicaciones son del tipo L, una ruta era del tipo P y el resultado de búsqueda de ruta deseada sería Iterable[P]. El resultado de la búsqueda del parche se debe armar preguntando a todos los buscadores de ruta (en algo como mapas de Google, pueden ser bicicleta, automóvil, paseo, metro, etc.) por sus sugerencias de ruta, que pueden definirse o no para un inicio particular/par de ubicación final.

Parece que hay dos maneras de hacer esto:

(a) definir un buscador de ruta como f: (L,L) => Option[P] y luego obtener el resultado a través de algo así como finders.map(_.apply(l1,l2)).filter(_.isDefined).map(_.get)

(b) definir un buscador de ruta como f: PartialFunction[(L,L),P] and then get the result via something like finders.filter (_.isDefined ((l1, l2))) .map (_.apply ((l1, l2))) `

Parece que usar una función que devuelva Option[P] evitaría una doble evaluación de los resultados, por lo que para un cálculo costoso, esto puede ser preferible a menos que uno almacene en caché los resultados. También parece que usando Option uno puede tener una firma de entrada arbitraria, mientras que PartialFunction espera un único argumento. Pero estoy particularmente interesado en escuchar a alguien con experiencia práctica sobre consideraciones menos inmediatas y de "mayor tamaño", como la interacción con la biblioteca de Scala. ¿Utilizaría un PartialFunction beneficios significativos al hacer disponibles ciertos métodos de la API de colecciones que podrían dar resultados de otra manera? ¿Sería ese código en general más conciso?

relacionadas pero distintas preguntas:

Respuesta

3

Se siente s like Option podría encajar mejor en su caso de uso.

Mi interpretación es que las funciones parciales funcionan bien para combinarse en rangos de entrada. Por lo tanto, si se define f en (SanDiego,Irvine) y g se define en (Paris,London), entonces puede obtener una función que se define sobre la entrada combinada (SanDiego,Irvine) y (Paris,London) haciendo f orElse g.

Pero en su caso, al parecer, las cosas suceden por una determinada ubicación (l1,l2) tupla y luego usted hace un trabajo ...

Si usted se encuentra escribiendo un montón de {case (L,M) => ... case (P,Q) => ...} entonces puede ser la señal de que las funciones parciales son un mejor ajuste.

De lo contrario opciones funcionan bien con el resto de las colecciones y se puede utilizar como éste en lugar de su (a) propuesta:

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

Dentro del para la comprensión p se levanta en un Traversable, por lo que don' t incluso tiene que llamar al filter, isDefined o get para omitir los buscadores sin resultados.

3

No es muy conocido, pero desde 2.8 Scala tiene un método collect definido en sus colecciones. collect es similar a filter, pero toma una función parcial y tiene la semántica que usted describe.

Cuestiones relacionadas