将功能转换为CPS

时间:2015-10-24 19:13:54

标签: haskell continuations

我有until的以下CPS实现:

until' p f x cc = p x (\y -> if y then cc(x)
                             else until' p f (f x (\z -> cc(z))) cc)

哪种类型检查好!现在,尝试CPS map

map' f (x:xs) cc = f x (\y -> map f xs (\ys -> cc(y:ys)))

另一种可能的实施方式:

map' f (x:xs) cc = cc(f x (\y cc' -> map f xs (\ys -> cc'(y:ys))))

然而,他们都没有打字。我在哪里做错了?

    Couldn't match expected type ‘([a1] -> t2) -> t1’
                with actual type ‘[(a1 -> t1) -> t]’
    Relevant bindings include
      y :: a1 (bound at test.hs:6:26)
      cc :: [a1] -> t2 (bound at test.hs:6:15)
      f :: a -> (a1 -> t1) -> t (bound at test.hs:6:6)
      map' :: (a -> (a1 -> t1) -> t) -> [a] -> ([a1] -> t2) -> t
        (bound at test.hs:6:1)
    The function ‘map’ is applied to three arguments,
    but its type ‘(a -> (a1 -> t1) -> t) -> [a] -> [(a1 -> t1) -> t]’
    has only two
    In the expression: map f xs (\ ys -> cc (y : ys))
    In the second argument of ‘f’, namely
      ‘(\ y -> map f xs (\ ys -> cc (y : ys)))’
Failed, modules loaded: none.

2 个答案:

答案 0 :(得分:3)

在CPS中重写时,延续会获得结果,因此如果您编写了地图函数的预期类型,那么:

mapk :: (a -> b) -> [a] -> ([b] -> r) -> r

所以continuation将结果列表作为参数。如果你看一下你的实现:

map' f (x:xs) cc = f x (\y -> map f xs (\ys -> cc(y:ys)))

yys应该具有相同的类型([b]),但是您尝试将它们与期望(:)和{b的{​​{1}}结合使用1}}。相反,你需要像:

[b]

答案 1 :(得分:0)

这是一个错字

map' f (x:xs) cc = f x (\y -> map f xs (\ys -> cc(y:ys)))

应该是:

map' f (x:xs) cc = f x (\y -> map' f xs (\ys -> cc(y:ys)))