gpt4 book ai didi

haskell - 生成 ByteString(或任何具有 ForeignPtr 组件的对象)的函数的纯度

转载 作者:行者123 更新时间:2023-12-03 22:11:24 25 4
gpt4 key购买 nike

由于 ByteString是具有 ForeignPtr 的构造函数:

data ByteString = PS {-# UNPACK #-} !(ForeignPtr Word8) -- payload
{-# UNPACK #-} !Int                -- offset
{-# UNPACK #-} !Int                -- length

如果我有一个返回 ByteString 的函数,然后给定一个输入,比如说一个常数 Word8 ,该函数将返回一个具有不确定 ForeignPtr 值的 ByteString - 至于该值将由内存管理器确定。

那么,这是否意味着返回 ByteString 的函数不是纯函数?如果您使用过 ByteString 和 Vector 库,显然情况并非如此。当然,如果是这样的话,它会被广泛讨论(并希望出现在谷歌搜索之上)。这种纯度是如何执行的?

问这个问题的原因是我很好奇使用 ByteString 和 Vector 对象所涉及的微妙点,从 GHC 编译器的角度来看,给定构造函数中的 ForeignPtr 成员。

最佳答案

无法观察 ForeignPtr 内的指针值来自Data.ByteString 之外模块;它的实现在内部是不纯的,但在外部是纯的,因为它确保只要您看不到 ByteString构造函数——你不能,因为它没有被导出。

这是 Haskell 中的一种常见技术:在底层实现一些不安全的技术,但暴露了一个纯接口(interface);在不影响 Haskell 安全性的情况下,您可以获得不安全技术带来的性能和功耗。 (当然,实现模块可能有错误,但你认为 ByteString 如果是用 C 编写的,它的抽象泄露可能性会更小吗?:))

就细微之处而言,如果您是从用户的角度说话,请不要担心:您可以使用 ByteString 和 Vector 库导出的任何函数而无需担心,只要它们不以 unsafe 开头。 .它们都是非常成熟且经过良好测试的库,因此您根本不应该遇到任何纯度问题,如果这样做,那是库中的错误,您应该报告它。

至于编写自己的代码以提供外部安全和不安全的内部实现,规则非常简单:保持引用透明性。

以ByteString为例,构造ByteStrings的函数使用unsafePerformIO分配数据 block ,然后他们对其进行变异并放入构造函数中。如果我们导出构造函数,那么用户代码将能够访问 ForeignPtr .这有问题吗?为了确定是否是,我们需要找到一个纯函数(即不在 IO 中),它可以让我们区分以这种方式分配的两个 ForeignPtrs。快速浏览the documentation说明有这样一个函数:instance Eq (ForeignPtr a)让我们区分这些。所以我们不能让用户代码访问ForeignPtr .最简单的方法是不导出构造函数。

总结:当您使用不安全的机制来实现某些东西时,请验证它引入的杂质不会泄漏到模块之外,例如通过检查你用它产生的值。

就编译器问题而言,您真的不必担心它们;虽然这些功能是不安全的,但它们不应该让你做任何比你在 IO 中所做的更危险的事情,除了违反纯度。 monad 开始。一般来说,如果你想做一些可能会产生意想不到的结果的事情,你就必须不遗余力地去做:例如,你可以使用 unsafeDupablePerformIO 如果您可以处理两个线程评估相同形式 unsafeDupablePerformIO m 的 thunk 的可能性同时。 unsafePerformIOunsafeDupablePerformIO 稍慢因为它可以防止这种情况发生。 (在使用 GHC 正常执行期间,您的程序中的 Thunk 可以由两个线程同时评估;这通常不是问题,因为两次评估相同的纯值应该没有不利的副作用(根据定义),但是在编写不安全的代码时,这是你必须考虑的事情。)

GHC documentation for unsafePerformIO (和 unsafeDupablePerformIO ,正如我在上面链接的那样)详细说明了您可能遇到的一些陷阱;类似的文档 unsafeCoerce# (应通过其可移植名称 Unsafe.Coerce.unsafeCoerce 使用)。

关于haskell - 生成 ByteString(或任何具有 ForeignPtr 组件的对象)的函数的纯度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8616861/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com