我正在尝试使用我在其他语言中在线找到的示例将一些功能转换为Scala中的CPS。
我们只有一个关于CPS的讲座,所有内容都应该是非常基础的,但我仍然不太了解如何正确进行转换。
这些是我在Scala上尝试在网上找到的示例。
pow2' :: Float -> (Float -> a) -> a
pow2' a cont = cont (a ** 2)
add' :: Float -> Float -> (Float -> a) -> a
add' a b cont = cont (a + b)
sqrt' :: Float -> ((Float -> a) -> a)
sqrt' a = \cont -> cont (sqrt a)
pyth' :: Float -> Float -> (Float -> a) -> a
pyth' a b cont = pow2' a (\a2 -> pow2' b (\b2 -> add' a2 b2 (\anb -> sqrt' anb cont)))
现在我开始做pow2',看起来像这样:
def pow2_k(a:Float, k:(Float => Float)) : Float =
(a*a)
def pow2_cont(n: Float) = pow2_k(n, (x: Float) => x)
起初我有k(a*a)
而不是简单的(a*a)
,这导致了奇怪的结果。
接下来,我尝试添加”,目前看起来像这样:
def add_k(a:Float, b:Float, k:(Float, Float => Float)) : Float =
(a+b)
def add_k_cont(n:Float,m:Float) = add_k(n,m (x: Float, y:Float => (n+m)))
这显然是错误的。我在编写正确的续篇时遇到麻烦。 有谁知道一个很好的网站,论文,视频等来说明CPS的转换和延续?我发现的大多数工具要么太短,没有示例,要么太复杂。我觉得对于这些我要转换的简单函数来说,并没有那么复杂...
谢谢。
答案 0 :(得分:1)
def pow2_k[A](f: Float, k: Float => A): A = k(f * f)
def pow2_cont(n: Float): Float = pow2_k(n, identity)
scala> pow2_cont(2.0f)
res0: Float = 4.0
scala> pow2_k(4.0f, println)
16.0
想象CPS转换的最简单方法可能是:
采用不在CPS中的功能
def square(f: Float): Float = f * f
使函数具有类型A
的泛型;将函数的第二个参数从旧函数的结果类型添加到A
中;并将函数的结果类型更改为A
def cpsSquare[A](f: Float, ret: Float => A): A = ???
在每个函数“返回”一个值的地方(当然请注意,Scala中的return
具有奇异的语义,因此return
确实是一种不好的代码味道),请传递该值返回到函数(我称这个函数ret
暗示发生了什么事)
def cpsSquare[A](f: Float, ret: Float => A): A = ret(f * f)
基本上,在CPS中,您无需返回值,而是使用要返回的值调用传递的函数(延续)。