在forkIO中使用sendFlush和sendChunkBS

时间:2016-08-30 07:15:29

标签: haskell concurrency yesod conduit

我正在开发一个Yesod应用程序,在尝试在sendFlush内使用sendChunkBSforkIO时遇到错误。

sendFlushsendChunkBS属于Monad m => Producer m (Flush Builder),但forkIO需要IO ()

以下是代码:

respondSource "" $ do
  sendFlush

  (rid, rwait) <- liftIO $ T.forkIO $
    do
      let loop = do
            output <- liftIO $ SB.recv targetSocket (2^11)
            liftIO $ putStrLn $ "SB.recv: " ++ BSC.unpack output

            when (not $ BS.null output) $
              do
                sendChunkBS output
                sendFlush
                loop
      loop

和错误:

Couldn't match expected type ‘IO a0’
            with actual type ‘C.ConduitM
                                i0 (C.Flush Data.ByteString.Builder.Internal.Builder) m0 ()’
Relevant bindings include
  loop :: C.ConduitM
            i0 (C.Flush Data.ByteString.Builder.Internal.Builder) m0 ()
    (bound at app/Main.hs:96:13)
In a stmt of a 'do' block: loop
In the second argument of ‘($)’, namely
  ‘do { let loop = ...;
        loop }’

2 个答案:

答案 0 :(得分:1)

我会尝试在forkIO;

之前添加对runConduit的来电
  (rid, rwait) <- liftIO $ T.forkIO $ runConduit $

您对forkIO的论证是一个ConduitM操作,runConduit 将其转换为IO动作。

答案 1 :(得分:0)

这种方法的标准方法是创建某种共享变量以在子线程和主线程之间进行通信,并使主线程弹出值来自变量, <CheckBox android:id="@+id/delete_checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:layout_marginTop="10dp" /> 它们具有适当的函数。我的建议是使用Software Transactional Memory (STM),可能类似于TBQueue