runST 与 unsafePerformIO 的实际影响

2023-11-26

我想要类似的东西

f :: [forall m. (Mutable v) (PrimState m) r -> m ()] -> v r -> v r -- illegal signature
f gs x = runST $ do
  y <- thaw x
  foldM_ (\_ g -> g y) undefined gs -- you get the idea
  unsafeFreeze y

我基本上处于与以前相同的位置这个问题维特斯评论道:

[I]如果你想在某个结构中保留多态函数,你需要专门的数据类型(例如 newtype I = I (forall a.a -> a))或 ImpredicativeTypes。

另请参阅这个问题。问题是,这些都是非常丑陋的解决方案。所以我提出了第三种选择,即通过运行“应该”的内容来完全避免多态性ST计算中IO反而。因此f变成:

f :: [(Mutable v) RealWorld r -> IO ()] -> v r -> v r
f gs x = unsafePerformIO $ do
  y <- thaw x
  foldM_ (\_ g -> g y) undefined gs -- you get the idea
  unsafeFreeze y

我感觉有点脏unsafe IO路线与“安全”路线相比ST路线,但如果我的选择是包装器或命令类型......显然,我不孤独。

有什么理由我不应该 use unsafePerformIO这里?这样的话,真的一点都不安全吗?是否有性能方面的考虑因素或其他我应该注意的事情?

- - - - - - - 编辑 - - - - - - - -

下面的答案向我展示了如何完全解决这个问题,这很棒。但我仍然对原来的问题感兴趣(暗示runST vs unsafePerformIO当使用可变向量时)用于教育目的。


我还不能说我完全理解问题陈述,但以下文件在 GHC 7.6.2 下编译时没有错误。它与您的第一个示例具有相同的主体(特别是不调用unsafePerformIO根本);主要区别在于forall被移到所有类型构造函数之外。

{-# LANGUAGE RankNTypes #-}
import Control.Monad
import Control.Monad.Primitive (PrimState)
import Control.Monad.ST
import Data.Vector.Generic hiding (foldM_)

f :: Vector v r => (forall m. [Mutable v (PrimState m) r -> m ()]) -> v r -> v r
f gs x = runST $ do
  y <- thaw x
  foldM_ (\_ g -> g y) undefined gs
  unsafeFreeze y

现在让我们来解决ST vs IO问题。它被称为的原因unsafePerformIO并不是unusablePerformIO是因为它带有编译器无法检查的证明负担:您正在运行的东西unsafePerformIOon 的行为必须表现为引用透明。自从ST操作带有(编译器检查的)证明,表明它们在执行时行为透明runST,这意味着使用时不再有危险unsafePerformIO在将进行类型检查的代码上ST比使用中的runST.

BUT:从软件工程的角度来看存在危险。由于证明不再经过编译器检查,因此将来的重构更容易违反安全使用的条件unsafePerformIO。因此,如果可以避免它(就像这里看起来的那样),您应该努力这样做。 (此外,“不再有危险”并不意味着“没有危险”:unsafeFreeze您拨打的电话有其自身的举证责任,您必须满足;但那时你已经必须满足证明责任ST代码正确。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

runST 与 unsafePerformIO 的实际影响 的相关文章

随机推荐

  • 在 Angular 2 中的对象的所有属性中搜索字符串

    如何使用 TS 在 Angular 2 中的对象的所有属性中搜索字符串 我在带有搜索框的表中呈现了一组客户 如果用户键入一个值 我想搜索所有属性值以推送与键入的值匹配的客户 export var CUSTOMER Client id 1 n
  • 在 PdfPCell 中右对齐文本

    我有一个可以生成 PDF 发票的 C 应用程序 此发票中有一个项目和价格表 这是使用生成的PdfPTable and PdfPCells 我希望能够右对齐价格列 但我似乎无法做到 文本总是在单元格中左对齐 这是我创建表的代码 PdfPTab
  • 用经度和纬度计算半径[重复]

    这个问题在这里已经有答案了 我试图确定两个位置 每个位置都有自己的纬度和经度值 彼此之间的距离是否在一定距离内 例如 3 英里半径 我有双值来表示每个位置的纬度和经度 Location 1 Double lattitude1 40 7143
  • Java Math.cos() 方法未按预期返回 0

    在 Windows 7 PC 上使用 Java 不确定这是否重要 并对应该返回 0 如 pi 2 的值调用 Math cos 而不是返回小值 但除非我误解 否则小值是与零相比远大于 1 ulp Math cos Math PI 2 6 12
  • 使用 jQuery 确定 Android 上的长按(长按、轻按按住)

    我已经能够成功播放使用 jQuery 和 HTML 页面在 Android 上实现 touchstart touchmove 和 touchend 事件 现在我想看看确定长按事件的技巧是什么 即点击并按住 3 秒 我似乎还无法弄清楚这一点
  • 如何使用 Backbone.Marionette 处理嵌套的 CompositeView?

    我正在使用 Backbone 进入更大规模的数据结构 并且遇到了通过 CompositeViews 很好地表示数据的情况 也就是说 CollectionView 周围添加了 附加内容 例如标题 按钮等 然而 我在将 CompositeVie
  • 如何创建可以从以编程方式创建的按钮调用的 Segue?

    在 Swift 中 我使用以下方法以编程方式创建了一个按钮 var button UIBarButtonItem title Tableau style Plain target self action tabBarTableauClick
  • 如何使用 JDBC 或 Hibernate 获取当前数据库事务 id?

    我在谷歌上查了一下 但找不到任何相关的东西 基本上 我想掌握长时间运行的事务 现在 我经历information schema INNODB TRX或者看看输出show engine innodb status找到trx id然后打开gen
  • 直接在函数声明上使用 function.prototype.bind

    为什么这是允许的 var f function console log this x bind x 1 为什么这不是或者更好为什么我在这种情况下会出现语法错误 function f console log this x bind x 1 那
  • 通过引用 C++ 中的模板函数传递数组

    下面的代码对我来说效果很好 include
  • 为什么 null 不是编译时常量?

    所以如果我有一个static final Object CONSTANT null 出于某种原因 如果我在另一段代码中引用它 例如doSomething CONSTANT 它不会在编译期间内联到代码中 所以而不是doSomething nu
  • Ionic 2:如何更新现有项目的 Ionic 库?

    在 Ionic 2 网站上找不到任何信息 例如 使用 Ionic 库 2 0 1 创建一个项目 如何将其更新到 Ionic 库 2 1 0 标准程序是什么 ionic lib update已弃用 如果您想更新 CLI 您需要运行 npm i
  • System.Web.Http.HttpPut 与 System.Web.Mvc.HttpPut 有什么不同

    之间有什么不同系统 Web Http HttpPut and System Web Mvc HttpPut 在 Web API 项目上使用 HttpPut 会导致错误 405 请求的资源不支持 http 方法 PUT 它们属于两个不同的框架
  • 如何知道选择了哪个单选按钮?

    我的 Ui 中有 3 个单选按钮位于同一个单选组中 他们是 var rbutton1 app createRadioButton dist 5 miles var rbutton2 app createRadioButton dist 10
  • 如何在iOS中的UITableViewCell中制作渐变背景?

    我按照下面的教程使用 CAGradientLayer 在 UITableViewCell 中制作渐变背景 http cocoawithlove com 2009 08 adding shadow effects to uitableview
  • 将字符串转换为Scheme中的代码

    如何将字符串转换为PLT方案中相应的代码 不包含string gt input port方法 例如 我想转换这个字符串 1 0 1 0 0 进入这个列表 1 0 1 0 0 是否可以在不打开文件的情况下执行此操作 方案有程序read用于从输
  • onEdit(e) 在附加组件中不起作用

    我编写了一个脚本 在本机电子表格中使用时效果很好 我现在尝试将其作为附加组件发布 并且发现onEdit e 不工作 当onOpen e and onInstall e 工作正常 我已经查看了有关授权模式和安装 启用附加组件的文档 但我认为我
  • 无法禁用 Core i7 中的硬件预取器

    我在尝试禁用 Core i7 系统中的硬件预取器时遇到错误 我按照链接中的方法进行操作如何以编程方式禁用硬件预取 在我的系统中 grep i msr boot config uname r CONFIG X86 DEBUGCTLMSR y
  • 无法解析的外部符号 _declspec(dllimport)

    我在 Visual Studio 中为我的控制台应用程序创建了一个 DLL 在我的 DLL 中 我有一个名为 Dialog MainMenu 的类 其中有一个 cpp 文件和一个 h 文件 以下错误消息 错误9错误LNK2001 无法解析的
  • runST 与 unsafePerformIO 的实际影响

    我想要类似的东西 f forall m Mutable v PrimState m r gt m gt v r gt v r illegal signature f gs x runST do y lt thaw x foldM g gt