Haskell错误:无法推断(随机a0)由

Haskell错误:无法推断(随机a0)由,haskell,Haskell,我在玩随机函数,它给出了一个无限的随机值列表,如第9章“学习Haskell非常好”所示。代码如下所示: randoms' :: (RandomGen g, Random a) => g -> [a] randoms' gen = let (value, newGen) = random gen in value : randoms' newGen 为了记录随机生成器,我将randoms'更改为以下内容: randoms'' :: (RandomGen

我在玩随机函数,它给出了一个无限的随机值列表,如第9章“学习Haskell非常好”所示。代码如下所示:

randoms' :: (RandomGen g, Random a) => g -> [a]
randoms' gen = let (value, newGen) = random gen
               in value : randoms' newGen
为了记录随机生成器,我将
randoms'
更改为以下内容:

randoms'' :: (RandomGen g, Random a) => g -> [(a, g)]
randoms'' gen = let (value, newGen) = random gen
                in (value, newGen) : randoms'' newGen
它按预期工作

然后我以列表理解的方式重写了它:

randoms''' :: (RandomGen g, Random a) => g -> [(a, g)]
randoms''' gen = random gen : [random gen' | (_, gen') <- randoms''' gen]
它再次正常工作,并给出与
randoms'
完全相同的结果

我想知道为什么类型推断对
randoms'
有效,但对
randoms'
无效。有人能告诉我为什么这两个不相等,以及如何修复
randoms'
的代码吗

此外,我还试验了具有类似结构的测试代码:

generate :: (Integral a, RealFrac b) => a -> (b,a)
generate m = let x = 1.2^^m in (x, ceiling x)

foo :: (Integral g, RealFrac a) => g -> [(a,g)]
foo gen = let (value, newGen) = generate gen
          in (value, newGen) : foo newGen

foo' :: (Integral g, RealFrac a) => g -> [(a, g)]
foo' gen = generate gen : [generate gen' | (_, gen') <- foo' gen]

foo'' :: (Integral g, RealFrac a) => g -> [(a, g)]
foo'' gen = [generate gen' | gen' <- gen : map snd (foo'' gen)]
generate::(积分a,RealFrac b)=>a->(b,a)
生成m=let x=1.2^^m in(x,天花板x)
foo::(积分g,realfraca)=>g->[(a,g)]
foo gen=let(value,newGen)=生成gen
in(value,newGen):foo newGen
foo':(积分g,RealFrac a)=>g->[(a,g)]
foo'gen=generate gen:[generate gen'|(_,gen')
asTypeOf
是标准函数,基本上是
const
的类型约束版本:

asTypeOf :: a -> a -> a
asTypeOf = const

使用此函数,我们可以确定
x
的类型,从而确定
的类型,因为
随机生成的类型是已知的。

您丢弃了由
随机生成的实际值。
(\u,gen>)使用
asTypeOf
的第一个解决方案解决了这个问题。但是,第二个解决方案
randomList
会产生几乎完全相同的错误消息(如果类型签名设置为单态,它会再次起作用)。我仍然不明白为什么
\uuu
的类型是任意的,仅仅因为它没有被使用;单态的情况下无论如何都没有这样的问题。也许单态和多态的情况下类型推断的机制有所不同?@Oyu我删除了错误的函数。我不知道为什么我尝试它时它会起作用。Eit她的方式是“使用”
random
调用结果的一部分。如果我们使用
let(val,gen)=random(mkStdGen 0):(a,StdGen)
,我们最终得到另一个生成器
gen
,具体取决于类型。对于
a~Int
,我们得到
(9106162675347478443411346387765 2103410263)
。对于
a~Char
,我们得到了
('\589059',40014 40692)
。毕竟,你必须经常调用
next
,以便在你的整个值范围内创建一个统一的分布。我已经尝试了一些在我的原始帖子末尾重新编辑的foo代码。你能给我一些意见吗?
(_, gen') <- randoms''' gen
randoms''' gen = random gen : [random gen' `asTypeOf` x | x@(_, gen') <- randoms''' gen]
asTypeOf :: a -> a -> a
asTypeOf = const