gpt4 book ai didi

haskell - 在 IO monad 中使用 monad

转载 作者:行者123 更新时间:2023-12-04 19:09:37 25 4
gpt4 key购买 nike

是否有与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 () 的函数.有什么办法可以让我跑 printMessages在 IO monad 中?

最佳答案

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

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

那么你可以使用getSink :: Protocol p => WebSockets p (Sink p)在 fork 之前捕获一个水槽,然后你可以用 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

关于haskell - 在 IO monad 中使用 monad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16450491/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com