【问题标题】:Converting functions to CPS将函数转换为 CPS
【发布时间】:2016-01-24 03:58:39
【问题描述】:

我有以下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.

【问题讨论】:

  • 你在递归调用中调用map而不是map'
  • 您不应该将答案编辑到您的问题中 - 一开始我很困惑,因为您的第一个版本现在可以使用...

标签: haskell continuations


【解决方案1】:

在 CPS 中重写时,延续会得到结果,因此,如果您编写预期的 map 函数类型,您将拥有:

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

所以延续将结果列表作为参数。如果你看看你的实现:

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

yys 应该具有相同的类型 ([b]) 但是您尝试将它们与 (:) 结合使用,这需要 b[b]。相反,你想要这样的东西:

mapk _ [] k = k []
mapk f (x:xs) k = mapk f xs (\rs -> k $ (f x):rs)

【讨论】:

  • f 大概也应该进行 CPS 转换,以进行完整的转换。
  • @dfeuer 你能给出一个 CPS f 的实现吗?
【解决方案2】:

这是一个错字

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)))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-10
    • 2018-01-27
    • 2015-12-16
    • 2020-10-31
    • 2016-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多