【问题标题】:Example of State and Free monad in ScalazScalaz 中的 State 和 Free monad 示例
【发布时间】:2014-05-31 00:27:41
【问题描述】:

有人可以举例说明如何使用 ScalaZ Free monad 吗?

例如,如果我有一个简单的 State 函数并且想要应用它 10,000 次,我会得到 StackOverflowError:

def setS(i: Int) :State[List[Int], Unit] = State { l => ( i::l, () ) }

val state = (1 to 10000).foldLeft( put(Nil :List[Int]) ) {
    case (st, i) => st.flatMap(_ => setS(i))
}

state(Nil)

据我了解,Free monad 可以帮助避免这种情况。我如何使用 Free monad 重写这段代码以不导致堆栈溢出?

【问题讨论】:

标签: scala scalaz


【解决方案1】:

正如我在上面的评论中所说,将 State 计算提升到 StateT[Free.Trampoline, S, A] 似乎应该可行:

import scalaz._, Scalaz._, Free.Trampoline

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

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

s(Nil).run

不幸的是,这仍然会溢出堆栈,但正如 Dave Stevens 所说,使用应用程序 *> 而不是 flatMap 进行排序可以解决问题:

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

s(Nil).run

我不知道为什么会这样,我已经 asked a new question 专门讨论了区别,但这应该让您开始使用 Free。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-31
    • 1970-01-01
    相关资源
    最近更新 更多