如何丢弃结果Scalaz国家遍历

问题描述:

例子:如何丢弃结果Scalaz国家遍历

import scalaz._ 
import Scalaz._ 

def setS(i: Int): State[List[Int], Unit] = modify(i :: _) 

val state = (1 to 1000000).toList traverseS setS 

val (finalState, result) = state(Nil) 

我的状态功能setSUnit结果类型。这意味着我对结果不感兴趣。然而,当我像这样一百万次运行我的状态时,我将以result集合结束,其中包含Unit的一百万个实例,我将立即丢弃val (finalState, _) = state(Nil)。这似乎很浪费。

有没有办法在没有收集结果的情况下运行这种状态转换?从example-of-state-and-free-monad-in-scalaz

解决方案:

import scalaz._ 
import Scalaz._ 
import Free._ 

def setS(i :Int) :State[List[Int], Unit] = modify(i :: _) 

val s = (1 to 1000000).foldLeft(state[List[Int], Unit](()).lift[Trampoline]) { 
    case (st, i) => st *> setS(i).lift[Trampoline] 
} 

val (finalState, result) = s(Nil).run 

我想你可以写这样的:

def traverseUnitS[S](t :Traversable[State[S, Unit]]) :State[S, Unit] = State[S, Unit] { 
    state0 => 
    val sout = t.foldLeft(state0)((s, st) => st.run(s)._1) 
    (sout,()) 
} 
+0

不幸的是,尽管它没有收集结果,但是使用上面的免费monad的速度却非常慢。 – 2014-10-27 19:10:28

+0

你也可以在'StateT [Trampoline,List [Int],_]'中使用'traverse_',但它会一样慢。 – 2014-10-28 01:43:23

使用traverseS_而不是traverseS

+0

随着traverseS_我得到堆栈溢出。我必须避免折叠State monad,因为它会以足够大的集合来打击堆栈。 – 2014-10-27 18:39:50

+0

这不提供问题的答案。要批评或要求作者澄清,请在其帖子下方留言。 – 2014-10-27 18:55:21

+0

@oɔɯǝɹ它不怎么样?问题是“如果没有收集结果,是否有办法进行这种国家转型?”这正是'traverseS_'所做的。 – rightfold 2014-10-27 18:56:59