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. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |