我正在创建一个Haskell应用程序,它在无限循环上生成随机数(仅在客户端请求时)。但是,我应该只为此目的使用纯函数。将randomIO
与unsafeperformIO
一起包裹而没有任何严重的稳定性或性能风险是否安全?
答案 0 :(得分: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
以下对全局,可能是随机变量的诱惑定义是不安全的:
rand :: Bool -> Int
rand True = unsafePerformIO randomIO
rand False = 0
问题是同一个表达式现在会产生不同的值:
main = do
print (rand True)
print (rand True)
在这里打印:
-7203223557365007318
-7726744474749938542
(至少在没有优化的情况下进行编译 - 但这只是强调了unsafePerformIO
不恰当使用的脆弱性。
答案 1 :(得分:0)
I am creating a Haskell application that generates a random number on an infinite loop (only when requested by a client). However, I should only use pure functions for that purpose. Is it safe to wrap randomIO with unsafeperformIO without any drastic stability or performance risk?
Aside from performance (no risk) or stability (small risk), consider also the fact that you are writing non-canonical Haskell for no good reason. Your code will be difficult for anyone else to maintain if you take this approach.