2013-05-08 29 views
5

liftIO'un tersi gibi bir şey var mı? Websockets kullanıyorum ve sunucudan iletileri ayrı bir iş parçacığında dinleyebilmek istiyorum.IO monad içinde bir monad kullanma

import Network.WebSockets 
import qualified Data.Text as T 
import Control.Monad.IO.Class 
import Control.Monad 
import Control.Concurrent 
import Control.Applicative 

printMessages :: WebSockets Hybi00() 
printMessages = forever $ do 
    resp <- receiveDataMessage 
    liftIO $ print resp 

run :: WebSockets Hybi00() 
run = do 
    liftIO . forkIO $ printMessages 
    forever $ do 
     line <- liftIO getLine 
     sendTextData . T.pack $ line 

main = connect "0.0.0.0" 8080 "/" run 

Yani printMessages sunucudan gelen mesajları dinler ve bunların baskısının devam: İşte yapıyorum. Sorun şu ki, forkIO, IO() döndüren bir işlev bekliyor. IO monadında printMessages'u çalıştırmamın bir yolu var mı?

+1

[ 'runWithSocket'] (http://hackage.haskell.org/packages/archive/websockets/latest/doc/html/ Belki de Network-WebSockets.html # v: runWithSocket)? Genel olarak, bir 'MonadIO m''den' IO'ya geçmek için, bazı 'runXY' işlevine gereksinim duyarsınız. –

cevap

5

Eğer bu hakkı anlıyorsam, başka bir iş parçacığı içinde ileti almak istemenin nedeni, ana iş parçacığının göndermek için kullanıcı girdisini beklemesidir.

the documentation10'dan bakıldığında, iş parçacığının rollerini tersine çevirirseniz daha kolay bir süreye sahip olacaksınız: ana iş parçacığındaki alma ve diğerinden eşzamansız olarak gönderme.

Sonra monads karıştırma bütün sorunu kaçınarak, daha sonra IO yaşayan sendSink :: Sink p -> Message p -> IO() ile kullanabileceğiniz çatallaşma önce bir lavabo kapmak için getSink :: Protocol p => WebSockets p (Sink p) kullanabilirsiniz.

başka deyişle

, böyle bir şey için kodunuzu yeniden:

sendMessages :: Sink Hybi00 -> IO() 
sendMessages sink = forever $ do 
    line <- getLine 
    let msg = textData . T.pack $ line 
    sendSink sink msg 

run :: WebSockets Hybi00() 
run = do 
    sink <- getSink 
    liftIO . forkIO $ sendMessages sink 
    forever $ do 
     resp <- receiveDataMessage 
     liftIO $ print resp 

main = connect "0.0.0.0" 8080 "/" run 
+1

Teşekkürler! Cevabınızı çalışma kodumu eklemek için değiştirdim. –

İlgili konular