使用Haskell手柄时,我感到有点不安全。即,我正在寻找两个功能(也许它们已经存在,在这种情况下,请原谅我的无知)。
Network.accept
返回)时,既可读又可写,我希望将它们转换为一对
只读和只写句柄,以便写入只读
处理将不会键入检查,反之亦然。 (也许可以实现
这使用幻像类型并包装IO功能吗?)
任何想法都欢迎。
最佳答案
您可能要考虑使用network conduit软件包。它将网络应用程序描述为具有两个“端点”的东西-一个接收器将数据推送到套接字中,一个接收器从套接字中读取数据:
type Application m = AppData m -> m ()
data AppData m Source -- ...
appSource :: AppData m -> Source m ByteStringSource
appSink :: AppData m -> Sink ByteString m ()
这样可以将书写部分和阅读部分完全分开。现在,您可以使用这样的源和接收器执行任何操作,甚至将它们传递到不同的线程并分别处理输入和输出。当然,它们中的每个只能读或写,具体取决于您赋予的端点。
如果要强制执行单线程处理,则可以限制自己将程序组件实现为
Conduit ByteString m ByteString
。这样的管道可以简单地变成Application
,例如asApp :: MonadIO m => Conduit ByteString m ByteString -> Application m
asApp cond ad = appSource ad $= cond $$ appSink ad
但是管道只能使用
await
请求数据,并使用yield
写入输出,否则将无法访问任何类型的句柄并且永远不会看到其任何端点,因此它无法在任何地方公开或泄漏它们。