The Free representation in scalaz differs from that article. I think I understand why, but I thought I've give it a go at explaining it here so I can be corrected.
The scalaz Free trait has 3 constructors, the first 2 line up with the article:
case class Return[S[+_]: Functor, +A](a: A) extends Free[S, A] // previously called Fill
case class Suspend[S[+_]: Functor, +A](a: S[Free[S, A]]) extends Free[S, A] // previously called Roll
But then there's this one:
case class Gosub[S[+_]: Functor, A, +B](a: Free[S, A], f: A => Free[S, B]) extends Free[S, B] // previously called FlatMap
The old name gives a good clue as to what this for: it wraps up a bind/flatMap operation into data. There's a type declaration soon after this that's a bit of a spoiler: this is about trampolining, turning usage of stack into usage of heap.
In the flatMap/bind operation for Free, instead of applying the function argument, it's wrapped up inside a Gosub:
final def flatMap[B](f: A => Free[S, B]): Free[S, B] = this match {
case Gosub(a, g) => Gosub(a, (x: Any) => Gosub(g(x), f))
case a => Gosub(a, f)
}
No inner application of the function means that the flatMap returns without consuming stack. Instead, we choose to use up heap by allocating an object that represents the flatMap. We're now free to build Free's of mega-depth using bind without worrying about hitting the stack limit.
At least, that's how I understand it.
- Nick
--
You received this message because you are subscribed to the Google Groups "scala-functional" group.
To unsubscribe from this group, send email to scala-function...@googlegroups.com.