Haskell中更安全的句柄?

13

使用Haskell Handles时,我感到有点不安全。具体而言,我正在寻找两个功能(也许它们已经存在,如果是这种情况,请原谅我的无知)。

  1. 当我获取一个句柄(例如通过 Network.accept 返回的句柄),该句柄既可读又可写时,我希望将它们转换为一对只读只写句柄,以便向只读句柄写入内容会出现类型检查错误,反之亦然。(也许可以使用幻影类型并围绕IO函数进行包装来实现此目的?)
  2. 在并发设置中,我发现多个线程可以写入同一个句柄,这会导致非常严重的后果。如何通过类型系统(如果可能)防止这种情况或者至少在运行时通过抛出异常被通知到这种情况?

任何想法都受欢迎。

2个回答

8
看起来 safer-file-handles 库可以满足你的需求。第一部分处理得很清楚。并发安全似乎是通过 RegionTregions 库处理的。虽然我没有使用过,但它看起来是一种非常普遍的方法。

2

您可能希望考虑使用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。这样的conduit可以轻松转换为像Application这样的形式。

asApp :: MonadIO m => Conduit ByteString m ByteString -> Application m
asApp cond ad = appSource ad $= cond $$ appSink ad

然而,一个conduit只能使用await请求数据并使用yield输出,否则它无法访问任何类型的句柄,也永远看不到其端点,因此它无法在任何地方暴露或泄漏它们。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接