2011-12-01 41 views
6

我是一個相對的斯卡拉初學者,想就如何在這似乎是它可以用函數返回選項或PartialFunction做一個着手實施一些建議。我已經閱讀了所有我能找到的相關帖子(參見問題底部),但這些帖子似乎涉及使用PartialFunction或將一個轉換爲另一個的技術細節;我正在尋找類型的答案「如果情況是X,Y,Z,然後使用A else B,但也考慮C」。斯卡拉:選擇函數返回選項與PartialFunction

我的示例用例是使用路徑查找器庫位置之間的路徑搜索。說的位置是L型的,一個路徑是P類型和所需的路徑搜索的結果將是一個Iterable[P]。應該通過詢問所有路徑查找器(在Google地圖中,這些可能是Bicycle,Car,Walk,Subway等)來獲取路徑建議,這些路徑建議可以或不可以爲特定的開始/結束位置對。

似乎那裏是去這兩種方式:

(一)定義路徑查找器作爲f: (L,L) => Option[P],然後通過一些得到的結果類似finders.map(_.apply(l1,l2)).filter(_.isDefined).map(_.get)

(B)定義的路徑查找器爲f: PartialFunction[(L,L),P] and then get the result via something like finders.filter(_.isDefined((l1,l2))).map(_.apply((l1,l2)))`

看起來像使用函數返回Option[P]將避免雙重評估的結果,所以對於昂貴的計算,這可能是更可取的,除非緩存結果。它也似乎使用Option可以有任意的輸入簽名,而PartialFunction需要一個參數。但是我特別感興趣的是從具有實踐經驗的人那裏聽到關於不那麼直接,更「更大的圖片」的考慮,比如與Scala圖書館的互動。使用PartialFunction在提供某些可能以其他方式獲得回報的API集合方法方面具有顯着優勢?這樣的代碼通常會更簡潔嗎?

相關但不同的問題:

回答

3

感覺像Option可能更適合你的用例。

我的解釋是,部分函數很適合在輸入範圍內進行組合。因此,如果f定義在(SanDiego,Irvine)之上並且g定義在(Paris,London)之上,那麼您可以通過執行f orElse g獲得通過組合輸入(SanDiego,Irvine)(Paris,London)定義的功能。

但在你的情況看來,事情的發生給定(l1,l2)位置的元組,然後你做了一些工作......

如果你發現自己寫了很多{case (L,M) => ... case (P,Q) => ...}那麼它可能是標誌,部分功能更合適。

否則選擇與合集的其餘部分運作良好,可以像這樣的,而不是你的(一)建議使用:

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

內的理解p提升到Traversable,所以你不」你甚至不得不打電話filterisDefinedget跳過發現者沒有結果。

3

這並不是衆所周知的,但由於2.8 Scala在其集合上定義了collect方法。 collectfilter類似,但採用了部分函數並具有您描述的語義。