2016-04-20 3 views
2

Здесь у меня есть функция, чтобы создать поток случайных чисел от 0 до 999.Haskell генерация случайных чисел с уместностью без явной рекурсии

randomHelp :: RandomGen g => g -> [Int] 
randomHelp g = zipWith (mod) (map fst $ iterate (next . snd) $ next $ snd $ split g) $ repeat 1000 

Я хотел бы, чтобы выбрать все числа из потока, определенных выше и каждый elem(i) и elem(i + 1) должны уважать пристойность. Например, их gcd должен быть одним. Все, что я могу думать, это функция сгиба, потому что я могу начать с аккумулятора, который содержит номер 1 (предположим, что 1 будет первым элементом, который я хочу показать), тогда я проверяю правильность функции fold и, если ее уважают, я добавляю элемент в аккумулятор, но проблема в программных блоках из-за stackoverflow, я думаю.

Вот функция:

randomFunc :: RandomGen g => g -> [Int] 
randomFunc g = foldl (\acc x -> if (gcd x (last acc) == 1) then acC++ [x] else acc) [1] (randomHelp g) 

Примечание: Я не хочу использовать явную рекурсию.

ответ

2

Право раз, вероятно, подходит лучше, что-то вроде:

import System.Random (RandomGen, randomRs, mkStdGen) 

randomFunc :: RandomGen g => g -> [Int] 
randomFunc g = foldr go (const []) (randomRs (1, 20) g) 1 
    where go x f lst = if gcd x lst == 1 then x: f x else f lst 

затем

\> take 20 . randomFunc $ mkStdGen 1 
[16,7,6,19,8,15,16,1,9,2,15,17,14,3,11,17,15,8,1,5] 

Doing так что вы можете создать список с помощью : вместо ++, которые могут привести к квадратное снижению производительности, и вы можете обойти вызов до last.

+0

Я действительно не понимаю, как это работает? Вы можете мне объяснить? – zaig

+0

@zaig это приложение 'foldr :: Foldable t => (a -> b -> b) -> b -> ta -> b', где' b' само является функцией, например 'c -> d ', поэтому сигнатура будет« (a -> (c -> d) -> c -> d) -> (c -> d) -> ta -> c -> d'. если вы следуете за подписью, должен иметь смысл, как это работает –

+0

Я все еще не понимаю, кто является функцией f? По порядку я бы сказал, что это будет 'randomRs', когда go будет вызываться, но' randomRs' принимает генератор, а 'lst' и' x' не являются генераторами. Я все еще немного смущен. Что мне не хватает? – zaig

Смежные вопросы