我正在阅读第9章(更多输入和更多输出),了解大好的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)
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节