Haskell中``randoms`函数如何工作?

时间:2017-06-23 21:38:24

标签: haskell

我正在按照Learn You A Haskell书来学习Haskell,而我无法理解randoms函数。该书将函数定义为:

randoms' :: (RandomGen g, Random a) => g -> [a]  
randoms' gen = let (value, newGen) = random gen in value:randoms' newGen    

现在我看到这个函数的方式是它以递归方式调用自身并将返回值附加到列表value。我不明白的是函数是如何返回的,因为每次它只是用一个新的随机种子调用自己!

2 个答案:

答案 0 :(得分:7)

我认为令人困惑的部分可能是在返回值中使用:

value:randoms' newGen 

这是一个列表,第一项是value,列表的其余部分是递归调用randoms' newGen返回的内容。

  

我不明白该函数是如何返回的,因为每次它只是用一个新的随机种子调用自己!

由于懒惰,如果您尝试访问返回列表的第二个(或更晚的)项,它将仅调用自身。这个列表不是,也不可能在内存中。 Haskell中的列表更像是食谱...在您尝试访问元素之前,Haskell并没有尝试弄清楚它是什么。

答案 1 :(得分:5)

作为粗略的比较,不要试图考虑如何返回无限列表,而是考虑Python生成器如何能够“返回”无限列表:一次yield一个元素,因为他们是必需的。

不会立即返回整个列表。每个元素都根据需要进行评估,并且该函数仅在需要时进行递归。

注意,我并没有声称Haskell的懒惰与Python的生成器一样,但在考虑这些函数时要记住它可能是一个有用的比较。

请参阅其他答案,了解为何会发生这种情况。