如何在Haskell中生成随机整数?

如何在Haskell中生成随机整数?,haskell,random,io,int,Haskell,Random,Io,Int,我试图用以下代码生成一个随机索引(Int):randomRIO(0,2::Int)。但是它会生成IO Int,所以我不能这样做:[1,2,3]!!随机索引。将IO Int转换为Int需要做什么?谢谢。您不能将IO a转换为a;但是您可以将使用a的函数转换为使用ioa的函数。两个最重要的转换是: (<$>) :: (a -> b) -> (IO a -> IO b) (=<<) :: (a -> IO b) -> (IO a ->

我试图用以下代码生成一个随机索引(Int):
randomRIO(0,2::Int)
。但是它会生成IO Int,所以我不能这样做:
[1,2,3]!!随机索引
。将IO Int转换为Int需要做什么?谢谢。

您不能将
IO a
转换为
a
;但是您可以将使用
a
的函数转换为使用
ioa
的函数。两个最重要的转换是:

(<$>) :: (a ->    b) -> (IO a -> IO b)
(=<<) :: (a -> IO b) -> (IO a -> IO b)

您不能将
IO a
转换为
a
;但是您可以将使用
a
的函数转换为使用
ioa
的函数。两个最重要的转换是:

(<$>) :: (a ->    b) -> (IO a -> IO b)
(=<<) :: (a -> IO b) -> (IO a -> IO b)
…此代码:
randomRIO(0,2::Int)
。但它会生成一个
IO Int

不,它是一个
IO Int
值。这样的值类似于过程语言中的“函数”
int f()
。如果这是Python,那么您也不能只编写

Python 3.5.2(默认,2017年11月23日,16:37:01)
有关详细信息,请键入“版权”、“信用”或“许可证”
IPython 6.1.0——一种增强的交互式Python。键入“?”以获取帮助。
在[1]中:导入随机
在[2]:def()中:
…:返回random.randint(0,2)
...: 
[3]:[1,2,3][f]
---------------------------------------------------------------------------
TypeError回溯(最近一次调用上次)
在()
---->1[1,2,3][f]
TypeError:列表索引必须是整数或片,而不是函数
相反,您需要调用该操作。只有这样才能产生一个
Int
数字。在大多数语言中,这只是通过提供参数来实现的,在本例中,只有空元组
()

但这混淆了两个不同的概念,即提供论据和产生副作用。(在本例中,副作用是修改内置随机生成器的状态,因此不会每次都得到相同的数字。)

Haskell做得更好,它有专门的操作员来整理副作用的顺序。正如丹尼尔·瓦格纳所说,这些是
fmap
>=
。但是,如果这些中缀运算符和高阶类型签名在您看来很神秘,那么您也可以使用Haskell的
do
表示法,它实际上只是对同一事物的语法糖:

main :: IO ()
main = do
   randomIndex <- randomRIO (0,2)
   print $ [1,2,3] !! randomIndex
foo之间的区别
…此代码:
randomRIO(0,2::Int)
。但它会生成一个
IO Int

不,它是一个
IO Int
值。这样的值类似于过程语言中的“函数”
int f()
。如果这是Python,那么您也不能只编写

Python 3.5.2(默认,2017年11月23日,16:37:01)
有关详细信息,请键入“版权”、“信用”或“许可证”
IPython 6.1.0——一种增强的交互式Python。键入“?”以获取帮助。
在[1]中:导入随机
在[2]:def()中:
…:返回random.randint(0,2)
...: 
[3]:[1,2,3][f]
---------------------------------------------------------------------------
TypeError回溯(最近一次调用上次)
在()
---->1[1,2,3][f]
TypeError:列表索引必须是整数或片,而不是函数
相反,您需要调用该操作。只有这样才能产生一个
Int
数字。在大多数语言中,这只是通过提供参数来实现的,在本例中,只有空元组
()

但这混淆了两个不同的概念,即提供论据和产生副作用。(在本例中,副作用是修改内置随机生成器的状态,因此不会每次都得到相同的数字。)

Haskell做得更好,它有专门的操作员来整理副作用的顺序。正如丹尼尔·瓦格纳所说,这些是
fmap
>=
。但是,如果这些中缀运算符和高阶类型签名在您看来很神秘,那么您也可以使用Haskell的
do
表示法,它实际上只是对同一事物的语法糖:

main :: IO ()
main = do
   randomIndex <- randomRIO (0,2)
   print $ [1,2,3] !! randomIndex

foo和
do的区别我经常想知道初学者是否可以在不掌握
(>>=)
或类似知识的情况下很好地使用
do
符号。sigfpe的文章是我见过的最接近于认真对待这种可能性的教程,因此,如果你喜欢这个答案,我强烈推荐它作为理解如何正确使用
do
块的下一步。但我真正的代码是:
newCard::Card newCard=do索引“我想要返回一张卡”–不,你不需要。除非你希望每场游戏中的每张牌都是一样的。@leftaroundabout所以只能在输出中生成随机数?谢谢你的帮助。我看到了这个系统。随机软件包,我想我可以用它来做我想做的事情……我经常想知道初学者是否可以在不首先牢牢掌握
(>=)
或类似知识的情况下很好地使用
do
符号。sigfpe的文章是我见过的最接近于认真对待这种可能性的教程,因此,如果你喜欢这个答案,我强烈推荐它作为理解如何正确使用
do
块的下一步。但我真正的代码是:
newCard::Card newCard=do索引“我想要返回一张卡”–不,你不需要。除非你希望每场游戏中的每张牌都是一样的。@leftaroundabout所以只能在输出中生成随机数?谢谢你的帮助。我看到了这个系统。随机软件包,我想我可以用它来做我想做的事情。。。
GHCi, version 8.2.1: http://www.haskell.org/ghc/  :? for help
Loaded GHCi configuration from /home/sagemuej/.ghci
Loaded GHCi configuration from /home/sagemuej/.ghc/ghci.conf
Prelude> :m +System.Random
Prelude System.Random> randomIndex <- randomRIO (0,2 :: Int)
Prelude System.Random> [1,2,3] !! randomIndex
1