2013-09-16 28 views
5

Istnieje przykład soczewki mapy Scalaz here: Dan Burton nazywa ją containsKey, a inspiruje ją rozmowa Edwarda Kmetta. Istnieje również coś o nazwie mapVPLens w Scalaz 7, które jest przydatne do modyfikowania wartości na mapie.Scalaz: jak skomponować soczewkę mapy za pomocą soczewki wartościowej?

Moje pytanie brzmi: jeśli mam soczewkę do modyfikacji typu V i soczewkę dla Map[K,V], w jaki sposób mogę je skomponować? Szukałem od dawna dobrego prostego przykładu, ale w Scalaz wciąż brak jest przykładów.

Jestem zainteresowany zarówno rozwiązaniami Scalaz 6, jak i Scalaz 7.

Odpowiedz

8

Jeśli obiektyw starasz się komponować z obiektywem mapie częściowy obiektyw, można po prostu użyć compose:

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

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

, a następnie:

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 

pamiętać, że jest Scalaz 7.

Jeśli obiektyw, który chcesz skomponować, nie jest częściowy, możesz to zrobić za pomocą ~:

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) 

Istnieje również metoda .partial, jeśli nie podoba ci się operator jednokierunkowy.

+0

Dzięki, to jest świetna odpowiedź. W końcu pracuję nad kompozycją soczewek współpracującą z moją aplikacją - mnóstwem kompilacji w czasie, bez runtime'owych sporów! –

+0

Podsumowując, lewą ręką jest dodanie '.partial' do soczewki wartości, gdy mamy do czynienia z mapą. –