2013-09-16 39 views
5

有一個Scalaz地圖鏡頭here的例子:丹·伯頓稱它containsKey,並且它是由愛德華Kmett談話的啓發。在Scalaz 7中還有一個叫mapVPLens的東西,它對修改地圖中的值很有用。斯卡拉斯:如何用有價值的鏡頭組合一個地圖鏡頭?

我的問題是:如果我有用於修改類型V的鏡頭和用於Map[K,V]的鏡頭,我該如何創作它們?我一直在尋找一個簡單的例子,但斯卡拉茲仍然缺乏一些例子。

我感興趣的是既Scalaz 6和7 Scalaz解決方案。

回答

8

如果你想與地圖鏡頭組成鏡頭部分的鏡頭,你可以用compose

import scalaz._, Scalaz._, PLens._ 

def headFoo[A] = listHeadPLens[A] compose mapVPLens("foo") 

然後:

scala> headFoo.get(Map("foo" -> List(42))) 
res0: Option[Int] = Some(42) 

scala> headFoo.get(Map("foo" -> Nil)) 
res1: Option[Nothing] = None 

scala> headFoo.get(Map("bar" -> List(13))) 
res2: Option[Int] = None 

注意,這是Scalaz 7.

如果你想組成的鏡頭不是部分的,你可以使用~

scala> def firstFoo[A, B] = ~Lens.firstLens[A, B] compose mapVPLens("foo") 
firstFoo: [A, B]=> scalaz.PLensFamily[Map[String,(A, B)],Map[String,(A, B)],A,A] 

scala> firstFoo.get(Map("foo" -> (42, 'a))) 
res6: Option[Int] = Some(42) 

還有一個.partial方法,如果你不喜歡單目運算符。

+0

謝謝,這是一個偉大的答案。我終於得到鏡頭組成與我的應用程序一起工作 - 大量的編譯時爭吵,沒有運行時間的爭吵! –

+0

總之,訣竅是在處理地圖時,將「.partial」添加到值鏡頭。 –