簡體   English   中英

ST參考是否透明?

[英]Is ST referentialy transparent?

為什么ST設計為不允許以下代碼,如wikibook所示 這篇文章似乎暗示如果允許的話, ST效應會泄漏到另一個ST ,但我真的不明白為什么。

似乎我無法運行特定的ST s (STRef sa) ST效果是否包含且引用是否透明,但這種使用仍然被視為無效?

Intuition告訴我, IOST語義之間存在差異,因為有一個IO和許多獨立的ST ,但我不確定。

> runST (newSTRef True)

<interactive>:5:8: error:
    • Couldn't match type ‘a’ with ‘STRef s Bool’
        because type variable ‘s’ would escape its scope
      This (rigid, skolem) type variable is bound by
        a type expected by the context:
          forall s. ST s a
        at <interactive>:5:1-21
      Expected type: ST s a
        Actual type: ST s (STRef s Bool)
    • In the first argument of ‘runST’, namely ‘(newSTRef True)’
      In the expression: runST (newSTRef True)
      In an equation for ‘it’: it = runST (newSTRef True)
    • Relevant bindings include it :: a (bound at <interactive>:5:1)

> :t newSTRef
newSTRef :: a -> ST s (STRef s a)

> :t runST
runST :: (forall s. ST s a) -> a

問題標題的答案多於問題本身,但仍然是:

是的,ST是參考透明的。

很長一段時間,這只是猜測和相信,只有今年我們有一個適當的證據:

Monadic封裝狀態的邏輯關系:在runST存在的情況下證明上下文等價
Amin Timany,LéoStefanesco,Morten Krogh-Jespersen,Lars Birkedal
POPL 2018有條件地接受
http://iris-project.org/ 預印PDF

我真的不明白你在問什么,所以我假裝你的問題是:

為什么ST設計為禁止runST (newSTRef True)

如果允許,它將不再是引用透明的:

main = do
    let r = runST (newSTRef True)
    evaluate (runST (writeSTRef r False))
    print (runST (readSTRef r))

此代碼將輸出False

main = do
    evaluate (runST (writeSTRef (runST (newSTRef True)) False))
    print (runST (readSTRef (runST (newSTRef True))))

此代碼(在每個用戶中內聯r的結果)將輸出True ,因為runST (newSTRef True)每個實例runST (newSTRef True)將分配新的STRef變量。

實際實現runST的方式可確保在ST s操作中分配的所有資源都無法轉義該操作。

IOST s之間的區別在於沒有runIO功能。 您可以創建多個獨立的IO操作,但沒有runIO它們runIO (它們只是值)。 實際運行IO操作的唯一方法是將其綁定到main並讓運行時系統選擇它(就像在main包含一個隱式runIO ),因此只有一個IO動作將在程序。

當然,這個單一動作可以通過組合多個較小的動作來組成,但最終它仍然是一個整體。 另一方面, runST允許獨立執行多個ST s動作。

暫無
暫無

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

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