2013-09-16 10 views
5

Es gibt ein Beispiel für ein Scalaz-Kartenobjektiv here: Dan Burton nennt es containsKey, und es ist inspiriert von Edward Kmett sprechen. Es gibt in Scalaz 7 auch etwas, das mapVPLens genannt wird, das nützlich ist, um Werte in einer Karte zu ändern.Scalaz: Wie erstellt man ein Kartenobjektiv mit einem Wert Objektiv?

Meine Frage ist: Wenn ich ein Objektiv zum Ändern von Typ V und ein Objektiv für eine Map[K,V] haben, wie kann ich sie komponieren? Ich habe eine Weile nach einem guten, einfachen Beispiel gesucht, aber es gibt immer noch eine Menge Beispiele in Scalaz.

Ich interessiere mich für Scalaz 6 und Scalaz 7 Lösungen.

Antwort

8

Wenn das Objektiv Sie versuchen, mit der Karte Linse zu komponieren eine Teillinse ist, können Sie einfach compose verwenden:

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

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

Und dann:

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 

Beachten Sie, dass diese Scalaz ist 7.

Wenn das Objektiv, das Sie zusammensetzen möchten, nicht teilweise ist, können Sie es mit ~:

machen
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) 

Es gibt auch eine .partial Methode, wenn Sie den unären Operator nicht mögen.

+0

Danke, das ist eine gute Antwort. Ich arbeite endlich mit der Linsenzusammensetzung, die mit meiner Anwendung arbeitet - viel Kompilierzeit, keine Laufzeitgerangel! –

+0

Zusammenfassend besteht der Trick darin, dem Wert-Objektiv ".partial" hinzuzufügen, wenn Sie mit einer Karte zu tun haben. –

Verwandte Themen