首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >链接Scalaz透镜集操作

链接Scalaz透镜集操作
EN

Stack Overflow用户
提问于 2013-12-15 20:17:37
回答 1查看 343关注 0票数 3

我正在努力学习scalaz7镜头。是否有更好的方法来链接集操作?

代码语言:javascript
复制
case class Outer(left: Inner, right: Inner)
case class Inner(top: Int, bottom: Int)

val left = Lens.lensu[Outer, Inner](
    (o,v) => o.copy(left = v),
    _.left
)
val right = Lens.lensu[Outer, Inner](
    (o,v) => o.copy(right = v),
    _.right
)
val top = Lens.lensu[Inner, Int](
    (o,v) => o.copy(top = v),
    _.top
)

val leftTop = left >=> top
val rightTop = right >=> top

val outer0 = Outer(Inner(10,20), Inner(30, 40))
val outer1 = rightTop.set(leftTop.set(outer0, 11), 33)

更新:

我有一种感觉,答案可能是使用国家单曲,虽然我几乎不明白为什么这似乎是可行的。想知道是否有更整洁的方法。

代码语言:javascript
复制
val modifier = for{
    _ <- leftTop := 11
    _ <- rightTop := 33
} yield Unit

modifier(outer0)._1   // = Outer(Inner(11,20),Inner(33,40))
EN

回答 1

Stack Overflow用户

发布于 2014-01-17 11:56:43

您可以在某种程度上简化State版本:

代码语言:javascript
复制
(leftTop := 11) >> (rightTop := 33) exec outer0

或者,如果你喜欢:

代码语言:javascript
复制
val modifier = (leftTop := 11) >> (rightTop := 33)
modifier.exec(outer0)

最初的状态版本看起来有点奇怪,因为<-语句中的for只是调用.flatMap的语法糖。稍微简化一下,leftTop := 11的结果有一个类似于State[Outer, Outer, Int]的类型,它大致相当于一个带有Outer => (Outer, Int)类型的函数。状态跟踪结果的Outer部分,并将Int部分传递给.flatMap。由于您不关心Int结果,所以将它分配给_并忽略它。

>>做同样的事情,它是一个忽略它的参数的.flatMap,与编写相同:

代码语言:javascript
复制
(leftTop := 11) flatMap (_ => rightTop := 33)

其结果是状态计算,它有一个辅助函数.exec,它以初始状态(outer0)运行计算,并返回最终状态(丢弃任何结果)。

如果您想避免使用State,那么您几乎必须按照您开始的方式来完成它。国家的全部目的是在各步骤之间传递中间结果,而不明确提及这些结果。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20599288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档