该 Haskell 代码到 Scala 的翻译是
sealed abstract class Free[S[_], A]
case class Return[S[_], A](a: A) extends Free[S, A]
case class Suspend[S[_], A](a: S[Free[S, A]]) extends Free[S, A]
Haskell 实现不需要Gosub
案例归功于懒惰的评估。这种表示法在 Scala 中也适用,但由于(严格评估和)缺乏尾部调用消除,它会导致堆栈溢出问题。为了使其堆栈安全,我们表示flatMap
懒洋洋地,如Gosub
(我认为FlatMap
会是一个更好的名字):
case class Gosub[S[_], B, C](a: Free[S, C], f: C => Free[S, B]) extends Free[S, B]
作为奖励,引入Gosub
使我们能够简化Suspend
to
case class Suspend[S[_], A](a: S[A]) extends Free[S, A]
因为我们不需要做flatMap
s 通过映射内容S[_]
不再——我们代表flatMap
明确地为Gosub
s.
因此,与 Haskell 表示不同,这种结果表示允许我们做任何我们想做的事情Free
无需Functor[S]
。因此,当我们的S
不是一个Functor
.