2011-12-01 16 views
6

Sono un principiante alla Scala e vorrei ricevere alcuni consigli su come procedere su un'implementazione che sembra possa essere eseguita con una funzione che restituisce Option o con PartialFunction. Ho letto tutti i post correlati che ho trovato (vedi in fondo alla domanda), ma questi sembrano coinvolgere i dettagli tecnici dell'uso di PartialFunction o della conversione di uno nell'altro; Sto cercando una risposta del tipo "se le circostanze sono X, Y, Z, quindi usa A else B, ma considera anche C".Scala: selezione della funzione di restituzione di un'opzione rispetto a una funzione parziale

Il mio caso d'uso di esempio è una ricerca di percorso tra posizioni utilizzando una libreria di ricerca di percorsi. Dire che le posizioni sono di tipo L, un percorso era di tipo P e il risultato di ricerca percorso desiderato sarebbe un Iterable[P]. Il risultato della ricerca delle patch dovrebbe essere assemblato chiedendo a tutti i cercatori di percorsi (in qualcosa come Google maps potrebbero essere biciclette, auto, a piedi, sottopassaggi, ecc.) Per i loro suggerimenti di percorso, che possono o non possono essere definiti per un particolare inizio/end location pair.

Sembra che ci siano due modi per andare su questo:

(a) definire un cercatore di percorso come f: (L,L) => Option[P] e quindi ottenere il risultato tramite qualcosa come finders.map(_.apply(l1,l2)).filter(_.isDefined).map(_.get)

(b) definire un cercatore di percorso come f: PartialFunction[(L,L),P] and then get the result via something like finders.filter (_.isDefined ((l1, l2)))

Sembra che l'utilizzo di una funzione che restituisce Option[P] eviti la doppia valutazione dei risultati, quindi per un calcolo costoso potrebbe essere preferibile a meno che non si memorizzino i risultati nella cache. Sembra anche che usando Option si possa avere una firma di input arbitraria, mentre PartialFunction si aspetta un singolo argomento. Ma sono particolarmente interessato a sentire da qualcuno con esperienza pratica su considerazioni meno immediate, più "più grandi", come l'interazione con la libreria di Scala. L'utilizzo di un valore PartialFunction ha significativi vantaggi nel rendere disponibili determinati metodi dell'API di raccolta che potrebbero ripagare in altri modi? Tale codice sarebbe generalmente più conciso?

Domande correlate ma differenti:

risposta

3

si sente s come Option potrebbe adattarsi meglio al tuo caso d'uso.

La mia interpretazione è che le funzioni parziali funzionano bene per essere combinate su intervalli di input. Quindi se f è definito su (SanDiego,Irvine) e g è definito su (Paris,London), è possibile ottenere una funzione definita sull'ingresso combinato (SanDiego,Irvine) e (Paris,London) facendo f orElse g.

ma nel tuo caso a quanto pare, le cose accadono per una data posizione (l1,l2) tuple e poi si fa un certo lavoro ...

Se vi trovate a scrivere un sacco di {case (L,M) => ... case (P,Q) => ...} allora può essere il segno che funzioni parziali sono una misura migliore.

Altrimenti opzioni funzionano bene con il resto delle collezioni e può essere utilizzato in questo modo al posto del tuo (a) proposta:

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

All'interno di comprensione p viene sollevato in una Traversable, in modo da don' Devo anche chiamare filter, isDefined o get per saltare i cercatori senza risultati.

3

Non è molto noto, ma poiché 2.8 Scala ha un metodo collect definito nelle sue raccolte. collect è simile a filter, ma prende una funzione parziale e ha la semantica che descrivi.

Problemi correlati