Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
包装到函数中的Haskell随机生成器始终返回相同的值_Haskell_Random - Fatal编程技术网

包装到函数中的Haskell随机生成器始终返回相同的值

包装到函数中的Haskell随机生成器始终返回相同的值,haskell,random,Haskell,Random,假设我在GHCi中执行以下代码: [unsafePerformIO (randomRIO (0,1)) | _ <- [1..10]]. 并尝试拨打: [f | _ <- [1..10]]. [f|up>unsafePerformIO不会使函数变得非纯 改为使用序列: sequence [randomRIO (0,1) | _ <- [1..10]] > [0,1,0,0,1,1,0,1,0,1] sequence[randomRIO(0,1)|u [0,1,0

假设我在GHCi中执行以下代码:

[unsafePerformIO (randomRIO (0,1)) | _ <- [1..10]].
并尝试拨打:

[f | _ <- [1..10]].

[f|up>
unsafePerformIO
不会使函数变得非纯

改为使用
序列

sequence [randomRIO (0,1) | _ <- [1..10]]
>
  [0,1,0,0,1,1,0,1,0,1]
sequence[randomRIO(0,1)|u
[0,1,0,0,1,1,0,1,0,1]

unsafePerformIO
不会使函数变得非纯

改为使用
序列

sequence [randomRIO (0,1) | _ <- [1..10]]
>
  [0,1,0,0,1,1,0,1,0,1]
sequence[randomRIO(0,1)|u
[0,1,0,0,1,1,0,1,0,1]

错误之处在于使用了
unsafePerformIO
,尤其是当您知道它不是一个函数时,对于相同的输入,它将有不同的输出

您使用的
unsafePerformIO
之所以不能按预期工作,是因为
f
不是一个函数,而是一个函数。它将只计算一次,每次都是相同的。您可以通过将其定义更改为

f :: Int
f = unsafePerformIO (putStrLn "generating" >> randomRIO (0,1))
“生成”仅打印一次

要使一个邪恶的“功能”,写


“功能”对于相同的输入有不同的输出!将
不安全
中的所有内容都放在一边,直到您确定需要并理解它,然后再放在一边。

您所做的错误是使用
unsafePerformIO
,特别是当您知道它不是一个函数时-它将为ame输入

您使用的
unsafePerformIO
之所以不能按预期工作,是因为
f
不是一个函数,而是一个函数。它将只计算一次,每次都是相同的。您可以通过将其定义更改为

f :: Int
f = unsafePerformIO (putStrLn "generating" >> randomRIO (0,1))
“生成”仅打印一次

要使一个邪恶的“功能”,写


对于相同的输入,“函数”有不同的输出!将
Unsafe
中的所有内容都放在一边,直到你确定你需要它并理解它,然后再放在一边。

unsafePerformIO
不要让函数变得非纯。使用
序列[randomiro(0,1)|使用
unsafePerformIO
是一个很大的“不要”在Haskell中。除非您确切知道自己在做什么,并且能够确保调用
unsafePerformIO
将产生纯函数,否则不要使用它。对于随机数生成,您必须使生成步骤在
IO
(或者在我喜欢的
MonadRandom
monad中,您需要安装
MonadRandom
包)。
unsafePerformIO
不要使函数非纯。使用
sequence[randomRIO(0,1)|使用
unsafePerformIO
是一个很大的“不要”在Haskell中。除非您确切知道自己在做什么,并且能够确保调用
unsafePerformIO
将产生纯函数,否则不要使用它。对于随机数生成,您必须使生成步骤在
IO
(或者在
MonadRandom
monad中,我更喜欢它,您需要安装
MonadRandom
包)。不使函数纯,您想说吗?@AdelNick,纯函数在相同的输入上总是有相同的输出。因此,您的
f=unsafePerformIO(randomiro(0,1))
仍然是纯的,即使有
unsafePerformIO
@AdelNick要澄清这一点,使
unsafePerformIO
如此不安全的是,编译器在大多数情况下基本上忽略了它的杂质,并将使用它的表达式视为纯的。这意味着,如果是纯表达式,它可以选择不重新计算它不需要重新评估,并且可以选择将其内联到其使用站点中,以使其得到比您想要的更多的评估。您想说的是,不使函数纯吗?@AdelNick,纯函数在相同的输入上总是有相同的输出。因此,您的
f=unsafePerformIO(randomRIO(0,1))
仍然是纯的,即使有
unsafePerformIO
@AdelNick要澄清这一点,使
unsafePerformIO
如此不安全的是,编译器在大多数情况下基本上忽略了它的杂质,并将使用它的表达式视为纯的。这意味着,如果是纯表达式,它可以选择不重新计算它不需要重新评估,并且可以选择在其使用站点中内联它,以便得到比您想要的更多的评估。感谢详细的回答谢谢详细的回答
print [g x | x <- [1,1,1,1,1,1,1]]