gpt4 book ai didi

haskell - Haskell 中随机数生成器的函数声明

转载 作者:行者123 更新时间:2023-12-02 16:48:42 26 4
gpt4 key购买 nike

我刚刚通过《Learn You a Haskell for Great Good》这本书开始学习Haskell,并读完第9章“输入和输出”。但当我尝试一个例子时,我遇到了一些奇怪的问题,大致可以描述为三个步骤。

1)书中的示例代码是

finiteRandoms :: (RandomGen g, Random a, Num n) => n -> g -> ([a], g)  
finiteRandoms 0 gen = ([], gen)
finiteRandoms n gen =
let (value, newGen) = random gen
(restOfList, finalGen) = finiteRandoms (n-1) newGen
in (value:restOfList, finalGen)

但是这个不能编译。错误信息是

/Users/learn_haskell/randomness.hs:12:15:
Could not deduce (Eq n) arising from the literal `0'
from the context (RandomGen g, Random a, Num n)
bound by the type signature for
finiteRandoms :: (RandomGen g, Random a, Num n) =>
n -> g -> ([a], g)
at /Users/learn_haskell/randomness.hs:10:18-69
Possible fix:
add (Eq n) to the context of
the type signature for
finiteRandoms :: (RandomGen g, Random a, Num n) =>
n -> g -> ([a], g)
In the pattern: 0
In an equation for `finiteRandoms': finiteRandoms 0 g = ([], g)
Failed, modules loaded: none.

2)我根据错误消息将代码更改为:

finiteRandoms :: (RandomGen g, Random a, Eq n, Num n) => n -> g -> ([a], g)  
finiteRandoms 0 gen = ([], gen)
finiteRandoms n gen =
let (value, newGen) = random gen
(restOfList, finalGen) = finiteRandoms (n-1) newGen
in (value:restOfList, finalGen)

编译没问题,但是运行这个函数就会出错

*Main> finiteRandoms 5 (mkStdGen 10)

<interactive>:18:1:
No instance for (Random a0) arising from a use of `finiteRandoms'
The type variable `a0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
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: finiteRandoms 5 (mkStdGen 10)
In an equation for `it': it = finiteRandoms 5 (mkStdGen 10)

3)最后,我根据前面的示例更改了代码。

finiteRandoms :: Int -> StdGen -> ([Int], StdGen)  
finiteRandoms 0 gen = ([], gen)
finiteRandoms n gen =
let (value, newGen) = random gen
(restOfList, finalGen) = finiteRandoms (n-1) newGen
in (value:restOfList, finalGen)

此时一切似乎都很好。

基本上我知道为什么第三段代码是对的,但是我不太明白前两步哪里出了问题。这些错误消息的真正含义是什么?顺便说一句,我在 Emacs 中使用 Haskell 模式,我不确定这是否相关。

最佳答案

第一个示例不起作用,因为您将变量 n 与 0 进行模式匹配。因此,您必须添加约束 Eq 才能正确进行类型检查。 Eq 类型类定义了函数 ==,如果您想检查两个变量是否相等,则需要它。

在第二个示例中,编译器无法确定您想要的输出的确切类型。但如果你明确给出它,它就会正常工作:

ghci> finiteRandoms 4 (mkStdGen 10) :: ([Int], StdGen)
([-2776415066813205131,-8883108635655729860,-2410613080667970943,-2829092335322664428],587898465 1924298326)

由于第二个示例中的类型签名是多态的,因此您必须指定要获取结果的确切类型。

如果您明确指定它们,您还可以获得其他类型的随机数:

ghci> finiteRandoms 4 (mkStdGen 10) :: ([Double], StdGen)
([0.7560066907787318,0.7768262448447909,0.3681854379838826,0.9076550534223906],587898465 1924298326)

第三个示例工作没有任何问题,因为在类型签名本身中,您已经明确提到了所需的确切输入和输出类型。另外值得注意的是,第三个示例不是多态的。

关于haskell - Haskell 中随机数生成器的函数声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20930972/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com