【问题标题】:Safer Handles in Haskell?Haskell 中更安全的句柄?
【发布时间】:2013-08-08 20:37:18
【问题描述】:
我在使用 Haskell Handles 时感觉有点不安全。也就是说,我正在寻找两个功能(也许它们已经存在,在这种情况下,请原谅我的无知)。
- 当我获得一个句柄(例如,由
Network.accept 返回)时,它
既可读又可写,我希望将它们转换成一对
read-only 和 write-only 句柄使得写入只读
句柄不会输入检查,反之亦然。 (也许可以实现
这使用幻像类型并包装 IO 函数?)
- 在并发设置中,我发现多个线程可能会写入同一个句柄,这会产生非常糟糕的后果。如何通过类型系统(如果可能)防止这种情况发生,或者至少在运行时通过抛出异常获得通知?
欢迎提出任何想法。
【问题讨论】:
标签:
haskell
concurrency
io
functional-programming
【解决方案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。这样的管道可以很容易地变成Applications 之类的
asApp :: MonadIO m => Conduit ByteString m ByteString -> Application m
asApp cond ad = appSource ad $= cond $$ appSink ad
但管道只能使用await 请求数据并使用yield 写入输出,否则无法访问任何类型的句柄并且永远看不到它的任何端点,因此它不能在任何地方暴露或泄漏它们。