簡體   English   中英

Palindrome 和 Danvy 對直接風格的評論

[英]Palindrome and Danvy's remark on direct style

這是一些代碼,以“直接樣式”確定列表是否是 n+1 比較中的回文

pal_d1 :: Eq a => [a] -> Bool
pal_d1 l = let (r,_) = walk l l in r
        where walk l           [] = (True,l) 
              walk l       (_:[]) = (True,tail l)
              walk (x:l) (_:_:xs) = let (r, y:ys) = walk l xs
                                    in (r && x == y, ys)      

可以在幾個例子上進行測試

-- >>> pal_d1 [1,2,1]
-- True

-- >>> pal_d1 [1,2,2,1]
-- True

-- >>> pal_d1 [1,2,3,4,2,1]
-- False

Danvy 在“ There and back again ”中聲稱,由於以下 CPS 風格解決方案中延續的非線性使用,沒有控制運算符(在 4.2 之前)沒有直接風格的解決方案:

pal_cps1 :: Eq a => [a] -> Bool
pal_cps1 l = walk l l (\_ -> trace "called" True) 
    where 
          walk  l          []  k = k l
          walk  l       (_:[]) k = k (tail l)
          walk (x:xs) (_:_:ys) k = walk xs ys (\(r:rs) ->  x == r && k rs)          

第一個代碼如何不與此斷言相矛盾?

(以及如何不線性使用延續?)

他沒有聲稱沒有控制操作員就沒有解決方案。

延續不是線性使用的,因此將此程序映射回直接樣式需要控制運算符。

這篇論文的背景是研究直接風格和 CPS 之間的系統轉換,而那段的主張是,如果以花哨的方式使用延續,從 CPS 回歸是很棘手的。

通過一些努力,您可以將其重新調整為一個不錯的形狀,但問題仍然存在,編譯器如何自動執行此操作?

(以及如何不線性使用延續?)

在本文中,延續位於andalso ( && ) 的右側,因此如果左側操作數為False則將其丟棄。

在操作語義中,您可以將延續視為評估上下文,並且在該視圖中丟棄延續對應於引發異常。 當然可以,但關鍵是這需要源語言中的額外機制。

CPS 代碼(在問題的原始版本中——因為由 OP 編輯)似乎有問題。 看起來應該是

      walk (x:xs) (_:_:ys) k  =  walk xs ys (\(z:zs) -> x == z && k zs)

非 CPS 代碼從中間開始比較,對長度為n的列表進行n `div` 2比較。 即使發現不匹配,它也會繼續測試,因此是"linear"

在這種情況下,CPS 代碼會立即退出,因為(False && undefined) == False成立; “非線性”也是如此。 兩者相等,因此第一個沒有說明第二個。

正如另一個答案所說,不調用延續相當於在沒有延續的代碼中拋出異常,該論文的作者顯然稱之為“直接[即非CPS(?)--wn]風格”。

(我沒有讀過論文)。

順便說一句,以“直接”風格對早期退出的解決方案進行編碼並不難。 我們將使用相同的海龜和兔子技巧來發現一半,同時反向構建前半部分,然后在 Haskell 或其等效的短路直接遞歸變體中調用and $ zipWith (==) first_half_reversed second_half second_half,使用嚴格的語言,例如 Scheme。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM