簡體   English   中英

保護管道的行為與使用等待的管道相同嗎?

[英]Do guarded pipes behave the same as pipes using await?

管道是一個非常優雅,非常簡單的迭代版本。 您可以使用原語awaityield非常輕松地編寫管道代碼。 Paolo Capriotti擴展了帶有防護管道的管道概念,它使用稍微復雜的tryAwait原語,它允許管道在輸入流程用完后執行一些終結。

受保護管道實施方案,重新定義await來講tryAwait

await = tryAwait >>= maybe discard return

我的問題是:如果我編寫針對更簡單的Pipes實現的代碼(使用awaityield ), 使用相同的代碼 ,如果我切換到受保護的管道實現,它的行為是否相同? 換句話說,在行為方面,保護管道代碼可以簡單地視為管道代碼的超集嗎?

這是發布Pipes的Gabriel。 我一直在與Paolo合作,我們在工作中有一個更優雅的實現,比他原來的提議更強大,更安全。 對您的問題的簡短回答是最終實現是原始Pipes的超集,您可以使用相同的行為和語義編寫與以前相同的代碼。

我甚至可以在這里簡單地總結一下。 Await和yield語句是管道可以放棄控制的唯一方式,因此如果上游或下游管道終止,我們會向每個方法附加一個回退。 后備永久地降級管道,它不能再重復失敗的操作。 失敗的await將管道降級為生產者,失敗的產量將管道降級為消費者。 如果生產者未能屈服或消費者未能等待,他們將被降級為基礎monad,后者不再失敗。

消費者和生產者現在是獨立的類型,並且沒有暴露。 除了缺少Await或Yield構造函數之外,它們與類型管道類型相同。 這是必要的,至少對於生產者類型是必要的,因為沒有可以禁止等待語句的管道的輸入類型。

Await和yield語句默認為終止作為其回退行為,這與以前的行為相同。 等待和收益率將被用於支持它們的降級州。 但是,一旦我們提出比tryAwait或tryYield更性感的名稱,您現在可以選擇提供自己的后備。

我還必須驗證Pipes仍然是這個擴展名的類別,但似乎很可能。 它也是100%類型安全,並使用類型來強制降級而不是布爾值和程序員證明不變。

編輯:一些有用的代碼來激發你的胃口(從github存儲庫中檢出“try”分支以使用擴展名):

printer = forever $ await >>= lift . print

take' n = replicateM_ n $ await >>= yield

fromList' = mapM_ (yieldOr (lift $ putStrLn "Undelivered elements))

diagnose = forever $ do
    x <- awaitOr (lift $ putStrLn "Await failed")
    yieldOr (lift $ putStrLn "Yield failed") x

> runPipe $ printer <+< take' 3 <+< diagnose <+< fromList [1..10]
1
2
3
Yield failed
Undelivered elements
> runPipe $ printer <+< take' 10 <+< diagnose <+< fromList [1..3]
1
2
3
Await failed

答案是肯定的。

隨着Hackage上當前管道的實現,等待管道在其上游終止時立即終止。 如果使用await函數,保護管道也是如此。 如果您需要在終止之前特別表現,您可以選擇使用tryAwait

此外,“保護管道”只是概念的臨時名稱,而我們正在制定集成其功能的最佳方式。 我認為他們不會單獨發布。

暫無
暫無

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

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