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 ?
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
.