我开始使用 state monad 来清理我的代码。我已经解决了我的问题,我处理了一个名为 CDR 的事务并相应地修改了状态。使用此功能执行状态更新,对于单个事务来说它工作得非常好。
def addTraffic(cdr: CDR): Network => Network = ...
这是一个例子:
scala> val processed: (CDR) => State[Network, Long] = cdr =>
| for {
| m <- init
| _ <- modify(Network.addTraffic(cdr))
| p <- get
| } yield p.count
processed: CDR => scalaz.State[Network,Long] = $$Lambda$4372/1833836780@1258d5c0
scala> val r = processed(("122","celda 1", 3))
r: scalaz.State[Network,Long] = scalaz.IndexedStateT$$anon$13@4cc4bdde
scala> r.run(Network.empty)
res56: scalaz.Id.Id[(Network, Long)] = (Network(Map(122 -> (1,0.0)),Map(celda 1 -> (1,0.0)),Map(1 -> Map(1 -> 3)),1,true),1)
我现在要做的是在迭代器上链接许多事务。我发现了一些效果很好但状态转换不需要输入的东西(通过 RNG 改变状态)
import scalaz._
import scalaz.std.list.listInstance
type RNG = scala.util.Random
val f = (rng:RNG) => (rng, rng.nextInt)
val intGenerator: State[RNG, Int] = State(f)
val rng42 = new scala.util.Random
val applicative = Applicative[({type l[Int] = State[RNG,Int]})#l]
// To generate the first 5 Random integers
val chain: State[RNG, List[Int]] = applicative.sequence(List.fill(5)(intGenerator))
val chainResult: (RNG, List[Int]) = chain.run(rng42)
chainResult._2.foreach(println)
我没有成功地尝试适应这一点,但我无法让他们类型签名匹配,因为我的状态函数需要 cdr(事务)输入
谢谢