我正在创建一个在无限循环上生成随机数的 Haskell 应用程序(仅在客户端请求时)。但是,我应该只为此目的使用纯函数。randomIO
在unsafeperformIO
没有任何严重稳定性或性能风险的情况下进行包装是否安全?
问问题
1140 次
2 回答
13
任何使用 都unsafePerformIO
应该证明结果值仍然是纯的。证明的严谨性取决于您和工作的重要性。例如,这种可悲的使用unsafePerformIO
andrandomIO
应该是安全的,因为你可以证明当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 回答