Scalaz: how to compose a map lens with a value lens?

核能气质少年 提交于 2019-12-06 01:39:44

问题


There's an example of a Scalaz map lens here: Dan Burton calls it containsKey, and it's inspired by the Edward Kmett talk. There is also something called mapVPLens in Scalaz 7 which is useful for modifying values in a map.

My question is: if I have a lens for modifying type V, and a lens for a Map[K,V], how can I compose them? I've been searching for a while for a good simple example, but there's still a dearth of examples in Scalaz.

I'm interested in both Scalaz 6 and Scalaz 7 solutions.


回答1:


If the lens you're trying to compose with the map lens is a partial lens, you can just use compose:

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

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

And then:

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

Note that this is Scalaz 7.

If the lens you want to compose isn't partial, you can make it so with ~:

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)

There's also a .partial method if you don't like the unary operator.



来源:https://stackoverflow.com/questions/18835140/scalaz-how-to-compose-a-map-lens-with-a-value-lens

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!