Scala: selección de opción de devolución de función versusfunction parcial
-
26-10-2019 - |
Pregunta
Soy un principiante relativo de Scala y me gustaría algunos consejos sobre cómo proceder con una implementación que parece que se puede hacer con una opción de devolución de función o con Funciones parciales. He leído todas las publicaciones relacionadas que pude encontrar (ver la parte inferior de la pregunta), pero estos parecen involucrar los detalles técnicos del uso de la función parcial o la conversión de una a la otra; Estoy buscando una respuesta del tipo "Si las circunstancias son x, y, z, entonces use un más b, pero también considere c".
Mi caso de uso de ejemplo es una búsqueda de ruta entre ubicaciones que usan una biblioteca de buscadores de rutas. Digamos que las ubicaciones son de tipo L
, una ruta era de tipo P
y el resultado de búsqueda de ruta deseado sería un Iterable[P]
. El resultado de la búsqueda de parche debe ensamblarse preguntando a todos los buscadores de rutas (en algo como Google Maps, estos pueden ser bicicletas, automóviles, caminatas, metro, etc.) para sus sugerencias de ruta, que pueden o no definirse para un inicio particular/ PAR DE UBICACIÓN FINAL.
Parece que hay dos formas de hacerlo:
(a) Defina un buscador de ruta como f: (L,L) => Option[P]
y luego obtenga el resultado a través de algo como finders.map( _.apply(l1,l2) ).filter( _.isDefined ).map( _.get )
(b) Defina 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 regresa Option[P]
evitaría la doble evaluación de los resultados, por lo que para un cálculo costoso esto puede ser preferible a menos que uno establezca los resultados. También parece usar Option
uno puede tener una firma de entrada arbitraria, mientras que PartialFunction
espera un solo argumento. Pero estoy particularmente interesado en escuchar a alguien con experiencia práctica sobre consideraciones menos inmediatas y más "de imagen más grande", como la interacción con la Biblioteca Scala. Usaría un PartialFunction
¿Tiene beneficios significativos al poner a disposición ciertos métodos de la API de colecciones que podría dar sus frutos de otras maneras? ¿Tal código generalmente sería más conciso?
Preguntas relacionadas pero diferentes:
- Inverso del método de ascensor de la Funcionidad Parcial
- ¿El diseño de la función parcial es ineficiente?
- Cómo convertir x => opción [r] a la función parcial [x, r
- ¿Existe una forma más agradable de levantar una función parcial en Scala?
- El cálculo costoso que ocurre tanto en ISDefined como en aplicar una función parcial
Solución
Se siente como Option
podría adaptarse mejor a su caso de uso.
Mi interpretación es que las funciones parciales funcionan bien para combinarse sobre los rangos de entrada. Así que si f
se define sobre (SanDiego,Irvine)
y g
se define sobre (Paris,London)
Luego 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 parece que las cosas suceden para un hecho (l1,l2)
Tuple de ubicación y luego trabajas ...
Si te encuentras escribiendo mucho 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, las opciones funcionan bien con el resto de las colecciones y se pueden usar así en lugar de su (a) propuesta:
val processedPaths = for {
f <- finders
p <- f(l1, l2)
} yield process(p)
Dentro de la comprensión p
se levanta en un Traversable
, así que ni siquiera tienes que llamar filter
, isDefined
o get
para omitir los buscadores sin resultados.
Otros consejos
No es tan conocido, pero como 2.8 Scala tiene un collect
Método definido en sus colecciones. collect
es parecido a filter
, pero toma una función parcial y tiene la semántica que describe.