2016-09-08 5 views
0

я играю с QuickCheck, и наткнулся на какой-то странное поведениеСоздать генератор элементов с бесконечным списком

sample $ elements [1..5] 

работает, как и ожидалось, однако

sample $ elements [1..] 

зависаний в GHCI, даже при использовании конечный тип, такой как Int

sample $ elements [(1::Int)..] 

Почему не распечатать произвольный (р не предназначенный :) большой Int s?

Update

Я проверил @ explanantion amalloy путем использования

sample $ elements ([1 .. ] :: [Int8]) 

который не прекращается.

ответ

4

elements выбирает элементы равномерно случайным образом, что означает, что в среднем оно достигнет length/2 элементов в списке. Для бесконечных значений это невозможно, и для больших конечных списков, таких как [1..] :: [Int], это все равно достигает 1 миллиарда элементов, по одному через связанный список. Довольно медленная операция!

+0

Спасибо, почему он «достигает длины/2 элемента» в среднем? – dimid

+0

Я имею в виду, подумайте об этом. В списке с элементами 'N', каков средний индекс? Середина - это среднее значение, и оно находится в индексе 'N/2'. Поскольку вы выбираете единообразно случайным образом, ваш средний индекс будет средним индексом списка. – amalloy

+0

Правильно, но зачем вам нужно проходить первые предметы '[len/2] - 1'? Если вы знаете максимальный 'Int', вы можете получить его в O (1), разделив 2. Извините, если мне не хватает чего-то очевидного, я начинаю с haskell. – dimid

1

Похоже, что elements плохо документирован. В дополнение к непустому аргументу должен быть конечный. См исходный код:

-- | Generates one of the given values. The input list must be non-empty. 
elements :: [a] -> Gen a 
elements [] = error "QuickCheck.elements used with empty list" 
elements xs = (xs !!) `fmap` choose (0, length xs - 1) 

Он пытается вычислить длину входного списка, который вызовет бесконечную петлю на бесконечном списке.

+0

На самом деле, как указал амаллой, список, о котором идет речь, конечно из-за типа '[Int]'. В зависимости от вашей машины, 'Int' может быть 32 или 64 бит. В первом случае компьютер с большим объемом ОЗУ может завершиться (в конечном итоге). В последнем случае у вас наверняка не хватит памяти. – crockeea