2016-07-24 89 views
1

我試圖理解延續傳遞和呼叫與電流延續。 按本頁: https://en.wikipedia.org/wiki/Monad_(functional_programming)#Continuation_monad 與CC方法呼叫被實現如下:當前延續調用忽略它自己的延續?

call_cc :: ((a -> (b -> r) -> r) -> (a -> r) -> r) -> (a -> r) -> r 
call_cc f k = f (\t x -> k t) k 

正如本signatureimplementation說明。

但是,我們可以看到x參數在這裏從來沒有使用過。 這是否意味着任何延續傳遞給f總是被忽略,最初的延續k總是替代它? 在這種情況下,這是否意味着call-with-cc只能調用一個級別較深且不多的功能? (因爲在正常控制流程中調用的下一個函數將被忽略)

在這種情況下,它似乎非常有限,它的實際用途是什麼?

回答

2

Here你可以用很具體的解釋發現的callCC更可讀的定義:

class (Monad m) => MonadCont m where 
    callCC :: ((a -> m b) -> m a) -> m a 

的MonadCont類提供callCC功能,它提供了與延續單子使用 逃逸持續機制。轉義 延續允許您中止當前計算並立即返回 值。它們在Error monad中獲得與throwError和catchError類似的效果。

Here你可以看到一些漂亮的例子如何使用它。

但一般情況下:callCC不會忽略輸入,但它會增強您的程序的執行方式。

你定義一些功能像

doSomething panicExit = do 
    ... 
    when failCondition $ panicExit inputToStartOver 
    ... 

,然後通過callCC doSomething

而正是這種panicExit輸入忽略擲樣轉換到正常延續已經引起了你的眼睛。你的程序沒有義務失效,但你可以隨心所欲。

+0

謝謝! 在這個例子中:https://en.wikibooks.org/wiki/Haskell/Continuation_passing_style#Deciding_when_to_use_k 這是否意味着調用k將返回到先前的contiunation(當前的),並且「return(show $ y - 4 )「將顯示y-4並結束程序? – lezebulon

+0

@lezebulon在'callC'ed'do'塊中調用'k'將完全忽略此次調用後的所有操作。所以'return(show $ y - 4)'只會在'y> 20'條件爲'假' – Odomontois

+0

是的時候完成,但是當被調用時會返回什麼?它和k一樣嗎? – lezebulon

1

(爲表述的緣故,讓我用更簡潔的語法,而不是真正的Haskell)

callcc f應用於給定函數f到當前的延續k如果這個延續k曾經在另一個延續x下被調用,後面的延續x確實被丟棄了

例如,在1 + callcc (\k -> 2 + (k 3)),可變k被綁定到外延續1 + []其中[]到其中的返回值應充滿。當這個k被應用時,如(k 3),內部延續1 + (2 + [])被丟棄。結果,整個表達式變爲1 + 3並且評估爲4

另一方面,在1 + callcc (\k -> 2 + 4)中,從不調用延續k,整個表達式產生1 + (2 + 4),即7

通過兩個例子結合上面,你可以做更復雜的東西像1 + callcc (\k -> 2 + (if some_complex_condition then (k 3) else 4)),這給1 + 3如果some_complex_conditiontrue,或1 + (2 + 4)否則。

總結和回答你的問題:

但是,我們可以看到,x參數在這裏從來沒有使用過。

x被丟棄如果延續k被調用;然而,當k而不是被調用時,x被應用於「正常」返回值,如在上面的示例中那樣。 (後一種情況對應於連續單子中的return操作。)

P.S.

爲了簡潔起見,我採用了直接的非單子語法。在Haskell使用延續單子,下面的例子

callCC (\k -> do r <- (k 3); return (2 + r)) 

調用外延續k丟棄所述內2 + []並返回3,而

callCC (\k -> do r <- (return 4); return (2 + r)) 

給出2 + 4

+0

不會是(如果some_complex_condition then(k 3)else * return * 4)? – lezebulon

+0

這就是我使用「更簡潔的語法而不是真正的Haskell」的地方。對於'1 + callcc(\ k - > 2 +(如果some_complex_condition then(k 3)else 4))''的'真正的Haskell'代碼將會是'do a < - callCC $ \ k - >(do b < - if some_complex_condition then k 3 else return 4; return $ 2 + b);返回$ 1 + a'。 Haskell中的繼續monad需要不同的語法(和鍵入)來表達可能會引發延續的語法... – FPstudent

+0

我在Haskell中添加了一個使用continuation monad的postscript。 – FPstudent