3

我正在将 Haskell 绑定到图像加载库,并且我想尽可能避免复制。加载图像时,我从 C 库中取回包含图像数据的数据结构。现在,这个结构在所有意图和目的上都是不可变的,但是从它读取数据到 Haskell 是一个 IO 操作。是否可以使用 unsafePerformIO (或者可能是 unsafeDupablePerformIO 以获得更好的性能)来避免将内存复制到 Haskell 数组或类似数组中?当然,我需要将数据结构指针封装在 ForeignPtr 或类似内容中,并确保无法以任何其他方式访问或修改指针。

在这种情况下,惯例是什么?

4

1 回答 1

9

如果数据在逻辑上确实是不可变的,那么 unsafePerformIO 或 FFI 作为纯函数导入是可以的。unsafePerformIO 本身并不是坏事,它只是将证明操作的责任从编译器转移到您身上,以确定操作是否具有引用透明性。现在,这实际上有时很难证明而且不明显,所以你正在为一个很难追踪的大错误引入一个机会,永远不要仅仅因为你不能想到一个假装某事是参考的错误透明但不意味着没关系。编译器非常聪明地利用机会来优化事物。因此,请确保您实际上证明了不可变的引用透明性,而不仅仅是说服自己您想不出任何可能出错的方法。但如果你的证据是可靠的,

请注意,当涉及到内存消耗时,这可能会产生后果,不可变值可能会保留在未评估的 thunk 中,并且由于 haskell 编译器仅通过 ForeginPtr 知道您的对象,它不知道保留的成本有多大,因此逻辑不变性可能不是如果您的不可变对象足够大,以至于使用 IO monad 的显式生命周期方面对您有用,就足够了。类型系统保证正确性,效率是另一回事。

于 2014-02-23T12:35:41.110 回答