2011-12-01 20 views
6

Göreceli bir Scala başlangıç ​​seviyesindeyim ve bir seçeneği geri döndürme seçeneğiyle veya Kısmi İşlev ile gerçekleştirilebilecek gibi görünen bir uygulamaya nasıl devam edileceğine dair bazı tavsiyelerde bulunmak istiyorum. Bulabildiğim tüm yayınları okudum (sorunun alt kısmına bakınız), fakat bunlar Kısmi İşlev'in kullanılması veya birinin diğerine dönüştürülmesiyle ilgili teknik detayların içerilmesi gibi görünüyor; "Koşullar X, Y, Z ise, sonra A'yı kullan, fakat C'yi de düşün" türünün bir cevabını arıyorum.Scala: Dönen işlev seçimi Seçenek veya Kısmi İşlev

Örnek kullanım örneğim, yol bulucu kitaplığı kullanan konumlar arasında bir yol araştırmasıdır. Konumların L türünde olduğunu, yolun P türünde olduğunu ve istenen yol arama sonucunun Iterable[P] olacağını varsayalım. Yama arama sonucu, tüm yol bulucularına (Google haritaları gibi bir şeyde Bisiklet, Araba, Yürüyüş, Metro, vb.) Yol önerileri için belirli bir başlangıç ​​için tanımlanabilecek veya belirlenmeyebilecekleri sorularak toplanmalıdır. son konum çifti.

(a) f: (L,L) => Option[P] gibi bir yol bulucu tanımlamak ve sonra finders.map(_.apply(l1,l2)).filter(_.isDefined).map(_.get) gibi bir şey aracılığıyla sonuç almak

(b) f: PartialFunction[(L,L),P] and then get the result via something like gibi bir yol bulucu tanımlayın:

bu konuda gitmek için iki yol var gibi finders.filter (_.isDefined ((l1, l2))) .map (_.apply ((l1, l2)))

Option[P] döndüren bir işlev kullanmak, sonuçların iki kez değerlendirilmesini engeller. Pahalı bir hesaplama için, sonuçlar önbelleğe alınmadıkça bu tercih edilebilir. Ayrıca PartialFunction tek bir argüman beklerken Option bir keyfi giriş imzası olabilir gibi görünüyor. Ama özellikle Scala kütüphanesi ile etkileşim gibi daha az anlık, daha "büyük resim" konuları hakkında pratik deneyime sahip birinden duymak ilgimi çekiyor. PartialFunction kullanmak, başka yollarla ödeme yapabilecek koleksiyon API'sinin belirli yöntemlerini kullanıma sunmada önemli yararlar sağlar mı? Bu kod genellikle daha özlü olur mu?

İlgili fakat farklı sorular:

cevap

3

O hissetmek Option gibi, kullanım durumunuza daha iyi uyabilir.

Benim yorumum, Kısmi İşlevlerin giriş aralıkları üzerinden birleştirilecek şekilde iyi çalışmasıdır. Bu nedenle, ve g üzerinden f tanımlanmışsa ve (Paris,London) üzerinden tanımlanmışsa, (SanDiego,Irvine) ve (Paris,London) kombine girişlerinde f orElse g yapılarak tanımlanan bir işlev alabilirsiniz.

Ama senin için herşeyin bazı işler yapmak sonra belirli bir (l1,l2) yeri başlığın için gerçekleşmesi ve görünüyor ...

Eğer {case (L,M) => ... case (P,Q) => ...} bir sürü yazı bulursanız o zaman kısmi işlevler o işareti olabilir daha iyi uyum sağlar.Eğer don böylece', anlama p için içinde

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

bir Traversable içine kaldırılır:

Aksi seçenekleri koleksiyonları geri kalanı ile iyi çalışmaz ve bunun yerine (a) teklifin bu gibi kullanılabilir Bulucuları sonuçsuz atlamak için filter, isDefined veya get numaralarını bile aramak zorundasınız.

3

Bu çok iyi bilinen bir şey değil, ancak 2.8 Scala'nın koleksiyonlarında tanımlı bir collect yöntemi bulunduğundan. collect, filter ile benzerdir, ancak kısmi bir işlev alır ve tanımladığınız semantiklere sahiptir.

İlgili konular