首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在IO monad中使用monad

在IO monad中使用monad
EN

Stack Overflow用户
提问于 2013-05-09 05:25:56
回答 1查看 383关注 0票数 5

有没有类似于liftIO的对立面?我正在使用websockets,我希望能够在单独的线程中监听来自服务器的消息。这就是我要做的:

代码语言:javascript
复制
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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-09 06:39:32

如果我没有理解错的话,你想在另一个线程中接收消息的原因是因为主线程将等待用户输入发送。

the documentation的角度来看,如果颠倒线程的角色,似乎会更容易:在主线程中接收,从另一个线程异步发送。

然后,您可以在派生之前使用getSink :: Protocol p => WebSockets p (Sink p)抓取一个接收器,然后可以将其与IO中的sendSink :: Sink p -> Message p -> IO ()一起使用,从而避免了混合monads的整个问题。

换句话说,将您的代码重新构造为如下所示:

代码语言:javascript
复制
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
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16450491

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档