有什么东西像是相反的liftIO吗?我正在使用websockets,我希望能够在一个单独的线程中侦听来自服务器的消息.这是我正在做的事情:
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
Run Code Online (Sandbox Code Playgroud)
因此,printMessages侦听来自服务器的消息并将其打印出来.问题是,forkIO期望一个返回的函数IO ().我有什么方法可以printMessages在IO monad中运行吗?
如果我理解这一点,你想要在另一个线程中接收消息的原因是因为主线程将等待用户输入发送.
从文档的角度来看,如果你反转线程的角色,你似乎会有一个更容易的时间:在主线程中接收,并从另一个线程异步发送.
然后你可以getSink :: Protocol p => WebSockets p (Sink p)在分叉之前用它来抓住一个水槽,你可以随之使用sendSink :: Sink p -> Message p -> IO ()它IO,避免混合monad的整个问题.
换句话说,将代码重构为以下内容:
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
Run Code Online (Sandbox Code Playgroud)