在Haskell中生成随机数

Mar*_*ark 4 random haskell

我正在阅读第9章(更多输入和更多输出),了解大好的Haskell.现在我要学习如何在Haskell中生成随机数(这太激动了!).这是本书的引文:

要手动创建随机生成器,请使用mkStdGenfunction.它有一种类型mkStdGen :: Int -> StdGen.它需要一个整数,并在此基础上给我们一个随机生成器.那么,让我们尝试使用randommkStdGenin串联得到(几乎)随机数.

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)
Run Code Online (Sandbox Code Playgroud)

这是什么?啊,对,该random函数可以返回Random类型类的任何类型的值,因此我们需要通知Haskell我们想要哪种类型.另外,我们不要忘记它会在一对中返回一个随机值和一个随机生成器.

问题是我没有得到这个错误,事实上,我可以做到以下几点:

*Main> :m + System.Random
*Main System.Random> random (mkStdGen 100)
(-3633736515773289454,693699796 2103410263)
Run Code Online (Sandbox Code Playgroud)

所以我的问题是为什么我可以在不获得异常的情况下评估此表达式?

Sar*_*rah 10

我猜赌,并说自从LYAH写完以来,GHCI的违约规则已经延长.这意味着在类型不明确的情况下,GHCI会尝试选择特定类型.在这种情况下,它看起来像random (mkStdGen 100)默认值(Integer, StdGen).

另一方面,如果我创建一个test.hs文件

import System.Random

foo = random (mkStdGen 100)
Run Code Online (Sandbox Code Playgroud)

...并尝试在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.
Run Code Online (Sandbox Code Playgroud)

如果我想要相同的结果,我将不得不修复类型foo,如下:

foo :: (Integer, StdGen)
foo = random (mkStdGen 100)
Run Code Online (Sandbox Code Playgroud)

有关Extended Defaulting的更多信息,请参阅GHC文档中的第2.4.8节