2014-12-06 52 views
2

我有時間難以轉換一個簡單的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' = ? 

難道不可能嗎?

回答

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 -> r) -> r中獲得Int,該函數返回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),即函數類型構造相關聯的權利。

+0

謝謝!現在我明白爲什麼它不起作用。但是 'square_cps x cont = cont(square x)'對我來說仍然不明確。它採用簽名中描述的所有類型並返回'r'。這意味着,foo :: Int - > Int可以像foo x y = x + y一樣實現。因爲foo也接受所有參數並返回Int。但是那給了我編譯器錯誤。 – 1ambda 2014-12-06 07:37:30

+2

當你定義:'foo x y = x + y'時,那麼'foo'的類型是Int - > Int - > Int',而不是'Int - > Int'。請參閱[這些答案](http://stackoverflow.com/questions/12659927/using-ghci-to-find-type)瞭解如何使用ghci打印表達式的類型。 – ErikR 2014-12-06 14:25:16