簡體   English   中英

Scala Cats State Monad

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM