Example of State and Free monad in Scalaz

两盒软妹~` 提交于 2020-01-01 03:19:05

问题


Can somebody give an example how to use ScalaZ Free monad ?

For example, if I have a simple State function and want to apply it 10,000 times, I'd get 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)

As I understand, Free monad can help avoid this. How would I re-write this piece of code using Free monad to not cause stack overflow ?


回答1:


As I say in a comment above, lifting the State computations into StateT[Free.Trampoline, S, A] seems like it ought to work:

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

Unfortunately this still overflows the stack, but as Dave Stevens notes, sequencing with the applicative *> instead of flatMap fixes the issue:

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

s(Nil).run

I'm not sure why this is, and I've asked a new question specifically about the difference, but that should get you started with Free.



来源:https://stackoverflow.com/questions/23965215/example-of-state-and-free-monad-in-scalaz

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!