Haskell,简单的延续

时间:2014-12-06 06:16:22

标签: haskell continuations

我很难转换简单的CPS功能

这是CPS风格的方形功能

-- from : http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style
square :: Int -> Int
square x = x * x

square_cps :: Int -> ((Int -> r) -> r)
square_cps = \cont -> cont (square x)
-- square_cps 3 print will write '9' out in console

现在,我想以相反的顺序更改函数参数

square_cps' :: ((Int -> r) -> r) -> Int
square_cps' = ?

这不可能吗?

1 个答案:

答案 0 :(得分:5)

首先对您对square_cps

的定义进行细微修正
square_cps :: Int -> ((Int -> r) -> r)
square_cps x = \cont -> cont (square x)
          ^^^

或者你可以写:

square_cps x cont = cont (square x)

请注意,即使类型签名使square_cps看起来只是一个参数的函数,这仍然有效。

现在,square_cps'的类型签名无法正常工作。它们的编写方式意味着您可以从Int获得(Int -> r) -> r,这是一个返回r的函数。

要将参数翻转到square_cps,请首先编写此等效类型签名:

square_cps :: Int -> (Int -> r) -> r
              ^      ^             ^--- result
              |       \--- second arg
              \--- first arg

并识别所示的参数。然后交换第一个和第二个参数将产生此签名:

square_cps' :: (Int -> r) -> Int -> r
square_cps' cont x = square_cps x cont

通常,签名a -> b -> c等同于a -> (b -> c),即函数类型构造函数与右侧相关联。