【发布时间】:2017-04-01 10:47:50
【问题描述】:
三周前我问了一个问题how does hgearman-client work?。在一些帮助下,我编写了一个简单的客户端应用程序,现在我正在工作端工作。下面的 worker 实现编译良好,运行无任何异常。唯一的麻烦是W.runWorker gc (return g) 不会被执行。如果我理解正确,这是 Haskell 懒惰和 return t Monad 包装的结果。但我一点也不知道如何摆脱这个问题。有人可以帮忙吗?
import qualified Control.Monad.State as S
import qualified Data.ByteString.Char8 as B
import qualified Network.Gearman.Client as C
import qualified Network.Gearman.Worker as W
import Network.Gearman.Internal (Function, Port)
import Network.Socket (HostName)
main :: IO ()
main = do
c <- connect
case c of
Left e -> error $ B.unpack e
Right gc -> do
(res, _) <- flip S.runStateT gc $ do
g <- (W.registerWorker name func)
let t = W.runWorker gc (return g)
return t >> return ()
return res
where
connect = C.connectGearman (B.pack "i") host port
host = "localhost"::HostName
port = 4730::Port
name = (B.pack "foo")::Function
func _ = B.pack "bar"
不幸的是,绑定t <- W.runWorker 的尝试以编译器异常结束。如果我以这种方式更改代码:
Right gc -> do
(res, _) <- flip S.runStateT gc $ do
g <- (W.registerWorker name func)
t <- W.runWorker gc (return ())
return t >> return ()
return res
编译失败并出现异常:
Couldn't match expected type `S.StateT
Network.Gearman.Internal.GearmanClient IO a0'
with actual type `IO GHC.Conc.Sync.ThreadId'
In a stmt of a 'do' block: t <- W.runWorker gc (return ())
In the second argument of `($)', namely
`do { g <- (W.registerWorker name func);
t <- W.runWorker gc (return ());
return t >> return () }'
IO GHC.Conc.Sync.ThreadId 是runWorker 的结果。
【问题讨论】: