将 IO 递归循环重构为 Haskell 中的 monad 折叠
Refactor an IO recursive loop into a monad folding in Haskell
我写了一个 tcp 服务器,这是我的主循环方法:
serverLoop :: Socket -> IO ()
serverLoop sock = do
(conn, _) <- accept sock
forkIO $ handleConn conn
serverLoop sock
(注:handleConn :: Socket -> IO ()
是我程序特有的函数。)
我想将其重构为更 monadic 的方式,这是我的尝试:
serverLoop :: Socket -> IO ()
serverLoop sock = foldl1 (>>) $ map go $ repeat sock
where go sock = (accept sock) >>= (forkIO . handleConn . fst) >> return ()
但这会使程序在我开始通过套接字发送数据时立即崩溃。
这是我的问题:为什么?有什么解决办法?
永远重复相同动作的惯用方式是forever
serverLoop :: Socket -> IO ()
serverLoop sock = forever $ do
(conn, _) <- accept sock
forkIO $ handleConn conn
我不知道你说的"more monadic"是什么意思,但是你的函数可以这样写:
serverLoop :: Socket -> IO ()
serverLoop sock = forever (accept sock >>= forkIO . handleConn . fst)
我写了一个 tcp 服务器,这是我的主循环方法:
serverLoop :: Socket -> IO ()
serverLoop sock = do
(conn, _) <- accept sock
forkIO $ handleConn conn
serverLoop sock
(注:handleConn :: Socket -> IO ()
是我程序特有的函数。)
我想将其重构为更 monadic 的方式,这是我的尝试:
serverLoop :: Socket -> IO ()
serverLoop sock = foldl1 (>>) $ map go $ repeat sock
where go sock = (accept sock) >>= (forkIO . handleConn . fst) >> return ()
但这会使程序在我开始通过套接字发送数据时立即崩溃。
这是我的问题:为什么?有什么解决办法?
永远重复相同动作的惯用方式是forever
serverLoop :: Socket -> IO ()
serverLoop sock = forever $ do
(conn, _) <- accept sock
forkIO $ handleConn conn
我不知道你说的"more monadic"是什么意思,但是你的函数可以这样写:
serverLoop :: Socket -> IO ()
serverLoop sock = forever (accept sock >>= forkIO . handleConn . fst)