2013-09-16 7 views
5

C'è un esempio di un obiettivo di mappa di Scalaz here: Dan Burton lo chiama containsKey ed è ispirato dal discorso di Edward Kmett. C'è anche qualcosa chiamato mapVPLens in Scalaz 7 che è utile per modificare i valori in una mappa.Scalaz: come comporre un obiettivo mappa con un obiettivo di valore?

La mia domanda è: se ho un obiettivo per modificare il tipo V e un obiettivo per un Map[K,V], come posso comporli? Ho cercato un po 'per un buon esempio semplice, ma c'è ancora una mancanza di esempi in Scalaz.

Sono interessato alle soluzioni Scalaz 6 e Scalaz 7.

risposta

8

Se l'obiettivo si sta cercando di comporre con la lente mappa è un obiettivo parziale, si può semplicemente utilizzare compose:

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

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

E poi:

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 

Si noti che questo è Scalaz 7.

Se l'obiettivo che si desidera comporre non è parziale, è possibile farlo con ~:

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) 

C'è anche un metodo .partial se non ti piace l'operatore unario.

+0

Grazie, questa è un'ottima risposta. Finalmente sto ottenendo la composizione delle lenti che funziona con la mia applicazione: un sacco di discussioni in fase di compilazione, nessun conflitto di runtime! –

+0

In sintesi, il trucco consiste nell'aggiungere '.partial' all'obiettivo value quando si ha a che fare con una mappa. –

Problemi correlati