是否有一些像
这样的签名功能lensMapState[S, T, A](lens : Lens[S, T]): State[T, A] => State[S, A]
使用语义运行所选部分的修改并获得结果
一个实现可能是
def lensMapState[S, T, A](lens: Lens[S, T]): State[T, A] => State[S, A] =
stateT => State { s =>
val (result, x) = stateT.run(lens.get(s))
(lens.set(result)(s), x)
}
但是如果使用monocle或scalaz.Lens更简单明了吗?
答案 0 :(得分:2)
我认为你要找的是这样的:
import scalaz._
import Scalaz._
case class Person(name: String, age: Int)
case object Person {
val _age = Lens.lensu[Person, Int]((p, a) => p.copy(age = a), _.age
}
val state = for {
a <- Person._age %= { _ + 1 }
} yield a
state.run(Person("Holmes", 42))
导致
res0: scalaz.Id.Id[(Person, Int)] = (Person(Holmes,43),43)
https://github.com/scalaz/scalaz/blob/series/7.1.x/core/src/main/scala/scalaz/Lens.scala中定义了许多与镜头/状态相关的功能 Monocle遵循类似的原则。据我所知,相关函数在monocle.state中定义。