繁体   English   中英

在IO monad中使用monad

[英]Using a monad inside the IO monad

是否有与liftIO相反的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

因此, printMessages侦听来自服务器的消息,并继续将其打印出来。 问题是, forkIO需要一个返回IO ()的函数。 有什么办法可以在IO monad中运行printMessages吗?

如果我理解此权利,那么您想要在另一个线程中接收消息的原因是因为主线程将等待用户输入的发送。

文档的角度看,如果您反转线程的角色,似乎会更轻松:在主线程中接收,从另一个线程异步发送。

然后可以使用getSink :: Protocol p => WebSockets p (Sink p)在派生之前抓取一个getSink :: Protocol p => WebSockets p (Sink p)器,然后将其与sendSink :: Sink p -> Message p -> IO () ,它位于IO ,避免了混合单子的整个问题。

换句话说,将您的代码重组为以下形式:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM