标签: unsafe-perform-io

针对unsafePerformIO的部门限制

在工作中已经有一些关于将其作为禁止使用unsafePerformIO和相关的部门范围政策的讨论.就个人而言,我并不介意,因为我一直认为,如果我发现自己想要使用它,通常意味着我需要重新思考我的方法.

这种限制听起来合理吗?我似乎记得在某个地方读到它主要是为了FFI,但是我不记得我现在读到的地方.

编辑:好的,那是我的错.它不会受到合理需要的限制,即.FFI.政策的重点更多是为了阻止懒惰和代码味道.

monads haskell coding-style unsafe-perform-io

6
推荐指数
3
解决办法
1370
查看次数

在randomIO上使用unsafeperformIO的风险

我正在创建一个Haskell应用程序,它在无限循环上生成一个随机数(仅在客户端请求时).但是,我应该只为此目的使用纯函数.randomIOunsafeperformIO没有任何严重稳定性或性能风险的情况下包装是否安全?

random haskell unsafe-perform-io

6
推荐指数
1
解决办法
983
查看次数

安全使用unsafeIOToSTM从数据库中读取?

在这个伪代码块中:

atomically $ do
  if valueInLocalStorage key
      then readValueFromLocalStorage key
      else do
        value <- unsafeIOToSTM $ fetchValueFromDatabase key
        writeValueToLocalStorage key value
Run Code Online (Sandbox Code Playgroud)

使用安全unsafeIOToSTM吗?文档说:

  • STM实现通常会多次运行事务,因此如果您的IO有任何副作用,您需要为此做好准备.

    基本上,如果事务失败,那是因为某个其他线程,wroteValueToLocalStorage并且当重试事务时,它将返回存储的值,而不是再次从数据库中获取.

  • STM实现将中止已知无效且需要重新启动的事务.这可能发生在unsafeIOToSTM的中间,因此请确保您没有获取任何需要释放的资源(在中止事务时忽略异常处理程序).例如,这包括使用Handles执行任何IO.出错可能会导致随机死锁.

    这让我很担心.从逻辑上讲,如果fetchValueFromDatabase没有打开新连接(即使用现有连接),一切都应该没问题.我还缺少其他陷阱吗?

  • 当IO运行时,事务可能已经看到不一致的内存视图.由于事务的实现方式,在整个程序中您期望为真的不变量在事务中可能不正确.通常这对程序员来说是不可见的,但是使用unsafeIOToSTM可以暴露它.

    key 是单个值,没有不变量可以打破.

haskell stm unsafe-perform-io

6
推荐指数
1
解决办法
161
查看次数

记住有效的功能

我开始研究一个将元胞自动机定义为局部转换函数的项目:

newtype Cellular g a = Cellular { delta :: (g -> a) -> a }
Run Code Online (Sandbox Code Playgroud)

无论何时g是a Monoid,都可以通过在应用本地转换之前移动焦点来定义全局转换.这给了我们以下step功能:

step :: Monoid g => Cellular g a -> (g -> a) -> (g -> a)
step cell init g = delta cell $ init . (g <>)
Run Code Online (Sandbox Code Playgroud)

现在,我们可以通过使用简单地运行自动机iterate.通过memo模仿每个步骤,我们可以节省很多(而且我确实意味着很多:它可以节省数小时)重新计算:

run :: (Monoid g, Memoizable g) => Cellular g a -> (g -> a) -> [g -> a]
run cell = iterate (memo . …
Run Code Online (Sandbox Code Playgroud)

haskell memoization unsafe-perform-io

5
推荐指数
0
解决办法
127
查看次数

对IORefs制造反击的困惑

我找到了一些示例代码,并稍微改了一下

counter = unsafePerform $ newIORef 0

newNode _ = unsafePerformIO $
              do
                i <- readIORef counter
                writeIORef counter (i+1)
                return i
Run Code Online (Sandbox Code Playgroud)

每次运行时返回1然后2然后3然后3等.

但是当我改变它

newNode = unsafePerformIO $
              do
                i <- readIORef counter
                writeIORef counter (i+1)
                return i
Run Code Online (Sandbox Code Playgroud)

然后我每次运行都得0.

为什么会发生这种情况,我该怎么做才能解决这个问题?

monads haskell unsafe-perform-io ioref

4
推荐指数
1
解决办法
1518
查看次数

如何使用putStrLn进行跟踪(Haskell)

我试图通过添加对"putStrLn"的调用来获取Haskell函数以显示它何时应用:

isPrime2 1 = False

isPrime2 n = do
    putStrLn n
    null (filter (==0) (map (mod n) (filter isPrime2 [2..(floor (sqrt(fromIntegral (n-1))))])))
Run Code Online (Sandbox Code Playgroud)

(最终目标是证明为什么一个版本的isPrime比另一个版本更有效.)

当我将上面的代码加载到GHCi中时,我收到错误:

无法将预期类型Bool与实际类型匹配m0 b0

我确定这是一个n00b错误.有人能告诉我正确的方法来完成我想要做的事情吗?

monads haskell unsafe-perform-io

4
推荐指数
1
解决办法
1189
查看次数

来自FFI和unsafePerformIO的不可变数据

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

这些案件的惯例是什么?

haskell ffi unsafe-perform-io

3
推荐指数
1
解决办法
153
查看次数

如何包装不安全的FFI?(Haskell的)

这是一个后续问题,是否有充分的理由使用unsafePerformIO?

所以我们知道

p_sin(double *p) { return sin(*p); }
Run Code Online (Sandbox Code Playgroud)

不安全,不能用unsafePerformIO.

但该p_sin函数仍然是一个数学函数,它以不安全的方式实现的事实是一个实现细节.我们并不完全希望矩阵乘法在IO中,因为它涉及分配临时内存.

我们如何以安全的方式包装这个功能?我们需要锁定,自己分配内存等吗?是否有处理此问题的指南/教程?

haskell ffi unsafe-perform-io

3
推荐指数
1
解决办法
143
查看次数

(已编辑)如何在没有IO的情况下在Haskell中获取随机数

我希望stdGen在没有IO的情况下,在每个调用中返回不同的函数.我尝试使用unsafePerformIO,如下面的代码.

import System.IO.Unsafe
import System.Random

myStdGen :: StdGen
myStdGen = unsafePerformIO getStdGen
Run Code Online (Sandbox Code Playgroud)

但是当我尝试调用myStdGenghci时,我总是得到相同的值.我受虐了unsafePerformIO吗?或者还有其他方法可以实现我的目标吗?

编辑 对不起,我想我应该更准确地描述我的问题.

实际上,我正在实现treap数据strutcure的变体,它需要一个特殊的"合并"操作.它依赖于一些随机性来保证摊销的O(log n)预期时间复杂度.

我试图使用一对像(Tree, StdGen)每个treap保持随机发生器.当向treap插入新数据时,我将使用random随机值给新节点,然后更新我的生成器.但我遇到了一个问题.我有一个函数empty,它将返回一个空的treap,我使用myStdGen上面的函数来获得这个treap的随机生成器.但是,如果我有两个空的treap,它们StdGen将是相同的.因此,在我将数据插入treap并且当我想合并它们之后,它们的随机值也将是相同的.因此,我失去了我依赖的随机性.

这就是为什么我想要一个某种"全局"随机生成器,它StdGen为每次调用产生不同的结果,这样每个空的treap可能会有不同的StdGen.

haskell unsafe-perform-io

3
推荐指数
3
解决办法
1322
查看次数

为什么在`accursedUnutterablePerformIO`中没有`seq`?

为什么accursedUnutterablePerformIO(又名inlinePerformIO)实施

accursedUnutterablePerformIO :: IO a -> a
accursedUnutterablePerformIO (IO a) = case a realWorld# of (# _, r #) -> r
Run Code Online (Sandbox Code Playgroud)

并不是

accursedUnutterablePerformIO :: IO a -> a
accursedUnutterablePerformIO (IO a) = case a realWorld# of (# s, r #) -> s `seq` r
Run Code Online (Sandbox Code Playgroud)

haskell ghc unsafe-perform-io

2
推荐指数
1
解决办法
287
查看次数

标签 统计

haskell ×10

unsafe-perform-io ×10

monads ×3

ffi ×2

coding-style ×1

ghc ×1

ioref ×1

memoization ×1

random ×1

stm ×1