我想使用IO Int
从Int
将System.Random.MWC
转换为unsafePerformIO
。它在ghci中起作用:
Prelude System.Random.MWC System.IO.Unsafe> let p = unsafePerformIO(uniformR (0, 30) gen :: IO Int)
Prelude System.Random.MWC System.IO.Unsafe> p
11
Prelude System.Random.MWC System.IO.Unsafe> :t p
p :: Int
然而在GHC
import System.Random.MWC
import System.IO.Unsafe
main :: IO()
main = do
gen <-createSystemRandom
print $! s 30 gen
s :: Int-> GenIO -> Int
s !k g = unsafePerformIO(uniformR (0, k - 1) g)
它返回
ghc: panic! (the 'impossible' happened)
(GHC version 7.6.3 for i386-unknown-linux):
make_exp (App _ (Coercion _))
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
答案 0 :(得分:5)
这里真的不需要unsafePerformIO
。只需将s
的类型更改为返回IO Int
,然后使用do-notation或bind运算符将结果提供给print
。
s :: Int -> GenIO -> IO Int
s k g = uniformR (0, k - 1) g
main :: IO ()
main = do
gen <- createSystemRandom
x <- s 30 gen
print x
或
main = do
gen <- createSystemRandom
print =<< s 30 gen
或
main = print =<< s 30 =<< createSystemRandom