[英]Embed async within a Monad implementing MonadIO
我有一些pipes-concurrency
代碼,如下所示:
-- this won't compile but will give you the gist of what's happening
pipeline :: MonadIO m => Consumer a m ()
main = do
(output, input) <- spawn Unbounded
async $ do runEffect $ fromInput input >-> pipeline
performGC
-- skipped the `output` pipeline code.
問題1 :這顯然不會編譯,因為runEffect
將返回MonadIO m => m ()
並且async
需要IO a
。 有沒有辦法做到這一點? 還是我被迫強迫管道在IO monad中包含效果?
問題2 :在實現MonadIO的Monad中嵌入異步甚至有意義嗎? 不知道我在這里是否能很好地表達自己。
謝謝!
這顯然不會編譯,因為
runEffect
將返回MonadIO m => m ()
並且異步需要IO a
那不是很正確。 IO
是一個實例MonadIO
讓你的輸出runEffect
可以傳遞給async
或如函數取MaybeT IO ()
也是MonadIO
實例)。
我想你要找的是什么liftIO :: IO a -> ma
,這將讓你的“升降機”的具體IO (Async a)
由歸國async
多態MonadIO
在你的類型的簽名要求的類型。
...
liftIO $ async $ do runEffect $ fromInput input >-> pipeline
performGC
沒有嘗試編譯這個; 您可能還需要提升功能的其他IO
部分。
問題2:在實現MonadIO的Monad中嵌入異步甚至有意義嗎? 不知道我在這里是否能很好地表達自己。
當然,如果您想在某些monad堆棧中進行並發,為什么不呢?
我正在嘗試做完全相同的事情,這是問題的核心:
$ :t async . runEffect
async . runEffect :: Effect IO a -> IO (Async a)
$
簡而言之,我希望提供這種類型的東西。 但是我真正想要的類型是:
someAsync . runEffect :: MonadIO m => Effect m a -> m (Async a)
不幸的是,我不確定如何實現這一目標。 當前,這似乎是不可能的,但不是因為管道並發,還是純粹由於異步的類型。
我認為我們應該將兩個庫的開發人員都指向這個問題,因為否則,我看不到如何獲得所需的類型。
編輯1 :我發現了這個問題,他們不想將MonadIO支持添加到異步中 。
編輯2 :我喜歡Pipes庫,但是我很難找到解決該問題的方法。 如果找不到該問題的答案,則可以使用Data.Conduit.Async中的緩沖區,因為它似乎可以很好地解決此問題。
編輯3 :看來,解決此問題的正確方法是使用Lifted-async 。 該庫提供以下方法:
async :: MonadBaseControl IO m => m a -> m (Async (StM m a))
只要為Monad實現MonadBaseControl IO,它就應該可以完全滿足您的期望。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.