考虑使用Lens,Conduit和Monad-Loops的以下Haskell代码:
type Broadcast = Int
type BroadcastChan = TChan Broadcast
data SessionState = SessionState
{ _broadcastChan :: BroadcastChan
}
makeLenses ''SessionState
type Session m = StateT SessionState m
type SessionIO = Session IO
-- This function requires the state and IO...
processBroadcast :: Broadcast -> Conduit Broadcast SessionIO Packet
processBroadcast = undefined
-- | Handles networking
protocol :: Conduit Packet SessionIO Packet
protocol = do
ch <- lift $ use broadcastChan
-- line 51:
whileJust_ (liftIO . atomically $ tryReadTChan ch) (\x -> yield $ processBroadcast x)
liftIO $ putStrLn "End"
我无法通过大量的提升来解决以下类型错误:
src\Burrito\Network.hs:51:61:
Couldn't match expected type `Packet'
with actual type `Conduit Broadcast SessionIO Packet'
Expected type: ConduitM Packet Packet SessionIO b0
Actual type: ConduitM
Packet (Conduit Broadcast SessionIO Packet) m0 ()
In the expression: yield $ processBroadcast x
In the second argument of `whileJust_', namely
`(\ x -> yield $ processBroadcast x)'
一些指导或建议将不胜感激。请记住,processBroadcast
要求Session处理状态以进行处理。
monad-loops docs:http://hackage.haskell.org/packages/archive/monad-loops/0.4.2/doc/html/Control-Monad-Loops.html
管道文档: http://hackage.haskell.org/packages/archive/conduit/1.0.6/doc/html/Data-Conduit.html
stm(TChan)docs: http://hackage.haskell.org/packages/archive/stm/2.4.2/doc/html/Control-Concurrent-STM-TChan.html
答案 0 :(得分:2)
这有效:
import Control
type Broadcast = Int
type BroadcastChan = TChan Broadcast
data SessionState = SessionState
{ _broadcastChan :: BroadcastChan
}
makeLenses ''SessionState
type Session m = StateT SessionState m
type SessionIO = Session IO
-- This function requires the state and IO...
processBroadcast :: Broadcast -> Conduit a SessionIO Packet
processBroadcast b = undefined
-- | Handles networking
protocol :: Conduit Packet SessionIO Packet
protocol = do
ch <- lift $ use broadcastChan
-- line 51:
whileJust_ (liftIO . atomically $ tryReadTChan ch) processBroadcast
liftIO $ putStrLn "End"
由于函数processBroadcast只处理单个广播(我假设),因此无需将管道的输入类型限制为Broadcast。为了在协议中使用它,该管道的输入类型必须与协议Conduit的输入类型匹配,这是协议,因此在协议中,将processBroadcast中的a实例化为Packet。