Haskell 访问依赖C资源时取消安全性能
我正在写绑定(第一次)。在C级,有一个函数可以分配某种资源,我们称之为Haskell 访问依赖C资源时取消安全性能,haskell,ffi,Haskell,Ffi,我正在写绑定(第一次)。在C级,有一个函数可以分配某种资源,我们称之为ParentRes。它返回IO(Ptr ParentRes)。每次创建ParentRes时,都会分配一个子资源,我们称之为ChildRes。这些内容都是静态的,子指针不能更改,当父资源被释放时,它被释放 现在需要注意的是:有一个函数可以获取指向父级的指针并返回指向子级的指针: foreign import ccall unsafe "…" c_get_child_res :: Ptr ParentRes -> IO
ParentRes
。它返回IO(Ptr ParentRes)
。每次创建ParentRes
时,都会分配一个子资源,我们称之为ChildRes
。这些内容都是静态的,子指针不能更改,当父资源被释放时,它被释放
现在需要注意的是:有一个函数可以获取指向父级的指针并返回指向子级的指针:
foreign import ccall unsafe "…"
c_get_child_res :: Ptr ParentRes -> IO (Ptr ChildRes)
我想使用
unsafePerformIO
编写类型为Ptr ParentRes->Ptr ChildRes
的包装器。有什么理由我不应该这样做吗?这里我根据我的实际经验来回答,我刚才是因为
不是很纯的“纯”函数
我可以用这样的话来表述:一切可能受秩序影响的事物
执行时间应始终保持在IO
中<代码>IO单子是哈斯克尔标准
是确保执行秩序的可靠方法。如果秩序重要,你的
函数应该位于IO
monad中
现在,如果不清楚为什么在这种特殊情况下顺序很重要,请记住
必须分配父资源和子资源,然后
他们被释放了。当它们被释放时,你不会得到相同的结果(但是
而不是分段错误),因此引用透明度被破坏。那么这些
依赖于资源的函数应保持在IO
中
而且,我不认为不可能同时分配不同的对象
单程序执行期间的地址。这将再次打破参考
透明度。嗯,你有什么需要吗?@gspr,嗯,这可能会减少一点样板。不管怎样,我已经编写了更复杂的帮助程序,它们通过“链”提取IO中的值,然后从IO中提取它们。不过,这个问题的答案仍然很有趣。不回答(有趣的)问题,但是:如果您决定这样做,您不必显式地使用
unsafePerformIO
,您只需从外部导入的类型中删除IO
。@ReidBarton,嗯,在教程中,我读到有人说在传递或接收指针时应该始终使用IO…正如我对一个似乎已被删除的答案所做的评论,因为您说子指针在父指针的生命周期内是相同的,那么getChildRes x
将始终具有相同的值,所以unsafePerformIO
应该是安全的。但是,您不希望将该函数的类型设置为ptra->ptrb
,因为有人可以执行getChildRes(castptrx)
-您应该为Ptr ParentRes
和Ptr ChildRes
提供一个新的类型包装器。