2016-08-30 5 views
1

私はYesodアプリケーションを開発中ですが、sendFlushsendChunkBSforkIOの内部で使用しようとしているときにエラーが発生しました。forkIOでsendFlushとsendChunkBSを使用する

sendFlushおよびsendChunkBSMonad m => Producer m (Flush Builder)ですが、forkIOIO()が必要です。ここで

はコードです:

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 }’ 

答えて

1

私はちょうどforkIOrunConduitへの呼び出しを追加しようとするだろう。

(rid, rwait) <- liftIO $ T.forkIO $ runConduit $ 

forkIOへのあなたの引数はConduitMアクションで、runConduit はIOアクションにそれを変換します。

+0

'runConduit'は' Data.Void.Void'を含む 'ConduitM'を必要とするので動作しませんが、代わりに' ConduitFlush'があります。 –

0

これに対する標準的なアプローチは、子スレッドとメインスレッドの間で通信するための何らかの種類の共有変数を作成し、メインスレッドのポップ値を変数から外し、適切な機能を持つsendを持つことです。私のお勧めは、Software Transactional Memory (STM)、おそらくTBQueueのようなものを使うことです。

関連する問題