Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 访问依赖C资源时取消安全性能_Haskell_Ffi - Fatal编程技术网

Haskell 访问依赖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

我正在写绑定(第一次)。在C级,有一个函数可以分配某种资源,我们称之为
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
提供一个新的类型包装器。