Haskell更安全的句柄?

tfb*_*boy 13 io concurrency haskell functional-programming

使用Haskell Handles时我觉得有点不安全.也就是说,我正在寻找两个功能(也许他们已经在那里,在这种情况下请原谅我的无知).

  1. 当我获得一个句柄(例如,通过返回Network.accept),这是可读可写的,我想将它们转换为一对 只读只写处理,使得写入只读手柄不会类型检查,反之亦然.(也许可以使用幻像类型和IO函数包裹来实现这一点?)
  2. 在并发设置中,我发现多个线程可能会写入同一个句柄,这会产生非常严重的后果.如何通过类型系统(如果可能)阻止这种情况,或者至少在运行时通过抛出的异常通知这种情况?

欢迎任何想法.

Car*_*arl 8

看起来更安全的文件句柄库可以满足您的需求.第一部分处理得非常清楚.并发安全似乎受到处理RegionT地区图书馆.我根本没有使用它,但它看起来像一个非常常见的方法.


Pet*_*lák 2

您可能需要考虑使用网络管道包。它将网络应用程序描述为具有两个“端点”的东西 - 一个接收器将数据推送到套接字,一个源从套接字读取数据:

type Application m = AppData m -> m ()

data AppData m Source -- ...
appSource :: AppData m -> Source m ByteStringSource
appSink :: AppData m -> Sink ByteString m ()
Run Code Online (Sandbox Code Playgroud)

这清楚地将写作和阅读部分分开。现在,您可以使用这样的源和接收器做任何您喜欢的事情,甚至将它们传递到不同的线程并分别处理输入和输出。当然,它们每个都只能读取或写入,具体取决于您为其指定的端点。

如果您想强制执行单线程处理,您可以限制自己将程序组件实现为Conduit ByteString m ByteString. 这样的导管可以很容易地变成Application类似

asApp :: MonadIO m => Conduit ByteString m ByteString -> Application m
asApp cond ad = appSource ad $= cond $$ appSink ad
Run Code Online (Sandbox Code Playgroud)

但是管道只能使用 请求数据并await使用 写入输出yield,否则无法访问任何类型的句柄,并且永远不会看到其任何端点,因此它无法在任何地方公开或泄漏它们。