Проблема в том, что random
принимает любой экземпляр RandGen
и возвращает случайное значение и новый генератор того же типа.Но случайное значение может быть любого типа с экземпляром Random
!
random :: (Random a, RandomGen g) => g -> (a, g)
Так что, когда вы вызываете random
во второй раз в рекурсии, оно не 'не знаю, какой должен быть тип first !Правда, вас это действительно не волнует (в конце концов, вы выбрасываете snd
), но выбор a может повлиять на поведение из random
.Таким образом, чтобы устранить неоднозначность, вы должны сказать GHC, кем вы хотите a .Самый простой способ - переписать ваше определение следующим образом:
randoms' gen = let (value, gen') = random gen in value : randoms' gen'
Поскольку вы используете value
как часть полученного списка, вы должны иметь тот же тип, что и a вподпись вашего типа - тип элемента результирующего списка.Неоднозначность разрешается, и повторяющиеся вычисления следующего случайного числа исключаются для загрузки.Есть способы устранить это более прямо (сохраняя дублирующиеся вычисления), но они либо уродливы и сбивают с толку, либо включают языковые расширения.К счастью, вы не должны сталкиваться с этим очень часто, и когда вы делаете, такой метод должен работать для устранения неоднозначности.
Эквивалентно и, возможно, более аккуратно, вы можете написать:
randoms' gen = value : randoms' gen'
where (value, gen') = random gen