【发布时间】:2014-03-21 00:40:49
【问题描述】:
我正在学习 Haskell 并学习我想生成一个随机 Int 类型。我很困惑,因为以下代码有效。基本上,我想要一个 Int 而不是 IO Int。
在 ghci 中这有效:
Prelude> import System.Random
Prelude System.Random> foo <- getStdRandom (randomR (1,1000000))
Prelude System.Random> fromIntegral foo :: Int
734077
Prelude System.Random> let bar = fromIntegral foo :: Int
Prelude System.Random> bar
734077
Prelude System.Random> :t bar
bar :: Int
所以当我尝试用 do 来结束它时,它失败了,我不明白为什么。
randomInt = do
tmp <- getStdRandom (randomR (1,1000000))
fromIntegral tmp :: Int
编译器生成以下内容:
Couldn't match expected type `IO b0' with actual type `Int'
In a stmt of a 'do' block: fromIntegral tmp :: Int
In the expression:
do { tmp <- getStdRandom (randomR (1, 1000000));
fromIntegral tmp :: Int }
In an equation for `randomInt':
randomInt
= do { tmp <- getStdRandom (randomR (1, 1000000));
fromIntegral tmp :: Int }
Failed, modules loaded: none.
我是 Haskell 的新手,所以如果有更好的方法来生成随机 Int 而不这样做,那将是首选。
所以我的问题是,为什么我的函数不起作用,有没有更好的方法来获取随机 Int。
【问题讨论】:
-
我建议你通读这一章:learnyouahaskell.com/input-and-output
-
使用 randomRIO 代替 randomR
-
如果您不想要
IO Int,则无法使用getStdRandom。毕竟,您想使用全局StdGen,从中生成一个值,然后更改全局StdGen。此操作有副作用,因此位于IOmonad 中。顺便说一句,答案在某种程度上取决于您使用randomInt的上下文,因此您应该将其添加到您的问题中。 -
我可以从 monad IO 中“提取”(因为没有更好的术语)底层 Int 吗?或者更好的是,我可以像使用带 Int 的函数一样使用 IO Int 吗?