[英]Scala Cats State Monad
我有一个类,它有一个生成结果的参数方法,并返回一个像自身这样的对象,但具有更新的状态供后续使用。
例如,下面包含这样一个类的简单示例以及我如何使用它:
case class Foo(x: Double) {
def bar(y: Double): (Foo, Double) = (Foo(x + y), x / (x + y))
}
val res = Vector(1.0,2.0,3.0,4.0).foldLeft((Foo(0), 0.0))((foo, x) => foo._1.bar(x))
res._1.bar(3.0)
我看过Cats State monad,并希望我可以用它来避免穿越状态(“x”成员)。 这里的示例接近我想要的但是返回新状态的函数没有任何参数,并且状态不会在循环操作中传递(而是在表达式之间传递)。 对于猫来说,我是一个完整的新手,但我是在咆哮错误的树吗?
下面你可以找到猫状态monad如何适应你的情况。 但是我对List[State[S, A]]
排序有一些问题,因为我在cat中有State[S, List[A]]
,所以我为此编写了一个函数sequence
。 如果有人知道该怎么做我会感兴趣:)
import cats.data._
case class Foo(x: Double)
def bar(y: Double): State[Foo, Double] = for {
foo <- State.get[Foo]
_ <- State.set(Foo(foo.x + y))
} yield foo.x / (foo.x + y)
val xs: List[State[Foo, Double]] = List(1.0, 2.0, 3.0, 4.0).map(bar)
def sequence(xs: List[State[Foo, Double]]): State[Foo, List[Double]] =
xs.foldLeft(State.pure[Foo, List[Double]](List.empty[Double])) { (acc, x) =>
for {
xs <- acc
xx <- x
} yield xx :: xs
}
val s = sequence(xs)
val ss = s.map(_.head)
s.run(Foo(0)).value
ss.run(Foo(0)).value
ss.flatMap(_ => bar(3)).run(Foo(0)).value
结果你得到了
res0: (Foo, List[Double]) = (Foo(10.0),List(0.6, 0.5, 0.3333333333333333, 0.0))
res1: (Foo, Double) = (Foo(10.0),0.6)
res2: (Foo, Double) = (Foo(13.0),0.7692307692307693)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.