6

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

4

2 回答 2

13

任何使用 都unsafePerformIO应该证明结果值仍然是纯的。证明的严谨性取决于您和工作的重要性。例如,这种可悲的使用unsafePerformIOandrandomIO应该是安全的,因为你可以证明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

以下对全局变量(可能是随机变量)的诱人定义并不安全:

rand :: Bool -> Int
rand True = unsafePerformIO randomIO 
rand False = 0

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

main = do
    print (rand True)
    print (rand True)

在这里打印:

-7203223557365007318
-7726744474749938542

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

于 2013-04-25T08:50:04.493 回答
0

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

除了性能(无风险)或稳定性(小风险)之外,还要考虑您无缘无故编写非规范 Haskell 的事实。如果您采用这种方法,其他人将难以维护您的代码。

于 2018-04-13T23:27:35.893 回答