探索 关于 Continuation Monad 的文章 在学习 Scala 3 的同时
我理解了整篇文章并且基本上将代码重写为 Scala 3 - 除了这个单一的棘手
goto
函数:
{-# LANGUAGE ScopedTypeVariables #-}
import qualified Control.Monad.Trans.Cont as C
goto = C.callCC $ \out -> let fn = out fn
in return fn
这部分利用了 Haskell 的特性递归值定义 - 见
let fn = out fn
.
问题:是否有可能让Scala表达类似于
let fn = out fn
这样的递归定义?如果没有,这样的东西怎么能被取代?我做了一些研究,了解到一些特殊情况可以通过递归使用惰性“流”来表示(例如,当我们可以递归定义惰性整数流时)。
附言。我的问题是关于递归定义表示。但是如果你对我对下面某些类型的定义感兴趣(注意,我的
Inc
就是他们在文章中所说的Cont
):
type Cont[X, R] = X => R
case class Inc[A, R](runCont: Cont[A, R] => R) {
def map[B](fn: A => B): Inc[B, R] = {
val c = (out: B => R) => runCont(a => out(fn(a)))
Inc(c)
}
def flatMap[B](fn: A => Inc[B, R]): Inc[B, R] = {
val c = (out: B => R) => runCont(a => fn(a).runCont(out))
Inc(c)
}
}
object Inc {
def return_[A, R](a: A) = {
val c = (out: A => R) => out(a)
Inc(c)
}
def callCC[A, B, R](fn: (A => Inc[B, R]) => Inc[A, R]): Inc[A, R] = {
val c = (out: Cont[A, R]) => fn(a => Inc(_ => out(a))).runCont(out)
Inc(c)
}
}