Я хотел бы создать эту функцию, которая выбирает случайный элемент из набора :
randElem :: (RandomGen g) => Set a -> g -> (a, g)
Простые реализации Listy могут быть записаны. Например, (Код обновлен, Проверенная работа):
import Data.Set as Set
import System.Random (getStdGen, randomR, RandomGen)
randElem :: (RandomGen g) => Set a -> g -> (a, g)
randElem s g = (Set.toList s !! n, g')
where (n, g') = randomR (0, Set.size s - 1) g
-- simple test drive
main = do g <- getStdGen
print . fst $ randElem s g
where s = Set.fromList [1,3,5,7,9]
Но с использованием !
! возникает линейный доступ к большому (случайным образом выбрано) n
. Есть ли более быстрый способ выбрать случайного элемента в наборе? В идеале, повторяющиеся случайные выборы должны создавать равномерное распределение по всем вариантам, что означает, что он не предпочитает некоторых элементов над другими.
Редактировать : некоторые великие идеи появляются в ответах, поэтому я просто хотел бросить пару Больше разъяснений на том, что именно я ищу. Я задал этот вопрос с множеством в качестве решения этой ситуации . Я предпочитаю ответы, что оба
У меня также есть эта любовь к рабочему коду, так ожидать (как минимум) +1 от меня, если ваш ответ включает в себя рабочий раствор.