在randomIO上使用unsafeperformIO的风险

Axe*_*nto 6 random haskell unsafe-perform-io

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

Joa*_*ner 12

任何使用都unsafePerformIO应该通过证明结果值仍然是纯粹的来证明.证明的严谨性取决于您和工作的重要性.例如,这种可怜的使用unsafePerformIO并且randomIO应该是安全的,因为你可以证明slowTrue返回任何东西时它会返回True.

import System.Random
import System.IO.Unsafe
import Data.Int

slowTrue = unsafePerformIO $ go
  where
    go = do
        x1 <- randomIO
        x2 <- randomIO
        if ((x1 :: Int16) == x2) then return True else go
Run Code Online (Sandbox Code Playgroud)

以下对全局,可能是随机变量的诱惑定义是不安全的:

rand :: Bool -> Int
rand True = unsafePerformIO randomIO 
rand False = 0
Run Code Online (Sandbox Code Playgroud)

问题是同一个表达式现在会产生不同的值:

main = do
    print (rand True)
    print (rand True)
Run Code Online (Sandbox Code Playgroud)

在这里打印:

-7203223557365007318
-7726744474749938542
Run Code Online (Sandbox Code Playgroud)

(至少在没有优化的情况下编译 - 但这只是强调了不恰当使用的脆弱性unsafePerformIO).

  • 我首先作为我的例子,但是我无法使GHC发挥得足以让它实际上是可观察的,因此这个例子. (2认同)