我正在阅读第13章(更多输入和更多输出)的了解您的Haskell以获得更好的。现在我要学习如何在Haskell中生成随机数(它非常令人兴奋!)。以下是本书的引文:
要手动制作随机生成器,请使用
mkStdGenfunction
。它的类型为mkStdGen :: Int -> StdGen
。它需要一个整数,并在此基础上给我们一个随机生成器。那么,让我们尝试使用random
和mkStdGenin
串联得到(几乎)随机数。
ghci> random (mkStdGen 100)
<interactive>:1:0:
Ambiguous type variable `a' in the constraint:
`Random a' arising from a use of `random' at <interactive>:1:0-20
Probable fix: add a type signature that fixes these type variable(s)
这是什么?啊,对,
random
函数可以返回属于Random
类型类的任何类型的值,因此我们需要通知Haskell我们想要哪种类型。另外,我们不要忘记它会返回一个随机值和一对随机生成器。
问题是我没有收到此错误,事实上,我可以执行以下操作:
*Main> :m + System.Random
*Main System.Random> random (mkStdGen 100)
(-3633736515773289454,693699796 2103410263)
所以我的问题是为什么我可以在不得到异常的情况下评估这个表达式?
答案 0 :(得分:10)
我打算猜测,并说自从LYAH写完以来GHCI的违约规则已经延长。这意味着在类型不明确的情况下,GHCI会尝试选择特定类型。在这种情况下,random (mkStdGen 100)
默认为(Integer, StdGen)
。
如果另一方面我创建了一个文件test.hs
import System.Random
foo = random (mkStdGen 100)
...并尝试将其加载到GHCI中,我得到:
test.hs:3:7:
No instance for (Random a0) arising from a use of ‘random’
The type variable ‘a0’ is ambiguous
Relevant bindings include
foo :: (a0, StdGen) (bound at test.hs:3:1)
Note: there are several potential instances:
instance Random Bool -- Defined in ‘System.Random’
instance Random Foreign.C.Types.CChar -- Defined in ‘System.Random’
instance Random Foreign.C.Types.CDouble
-- Defined in ‘System.Random’
...plus 33 others
In the expression: random (mkStdGen 100)
In an equation for ‘foo’: foo = random (mkStdGen 100)
Failed, modules loaded: none.
如果我想要相同的结果,我必须修改foo
的类型,如下所示:
foo :: (Integer, StdGen)
foo = random (mkStdGen 100)
有关延迟默认的详细信息,请参阅section 2.4.8 in the GHC docs