加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scalaz中State和Free monad的例子

发布时间:2020-12-16 18:47:40 所属栏目:安全 来源:网络整理
导读:有人可以举例说明如何使用 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
有人可以举例说明如何使用 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重写这段代码,不会导致堆栈溢出?

解决方法

正如我在上面的评论中所说,将状态计算提升为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

不幸的是,这仍然溢出堆栈,但正如戴夫史蒂文斯指出的那样,使用应用程序*>进行排序.而不是flatMap修复了这个问题:

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

s(Nil).run

我不确定为什么会这样,而且我已经明确了解了这个差异,但这应该让你开始使用Free.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读