Как выбрать случайные значения в ST-монаде?

#haskell #random #monad-transformers

#haskell #Случайный #монада-трансформеры

Вопрос:

Если у меня есть генератор случайных значений в RVar монаде

 ranfu :: RVar Bool
  

и функция более высокого порядка, которая выполняет какой-то обход в (например) ST монаде

 stTrav :: PrimMonad m => (Int -> m b) -> m [b]
  

тогда как я мог бы использовать ranfu в цикле этого обхода? Нужно ли мне передавать состояние RVar через an STRef , или есть лучший способ?

Комментарии:

1. Ммм, о каком «лучшем способе» ты думаешь? ST Насколько я понимаю, само по себе нет ничего случайного. AFAIK есть три способа «распаковать» RVal , и это runRVar , sampleRVar и sampleState . Если вы ST можете каким-то образом предоставить MonadRandom экземпляр, вы можете использовать 2-й.

2. Я бы не ожидал, что это будет законно. ST предполагается, что он детерминирован после его запуска; случайность нарушает это.

3. @LouisWasserman конечно, сначала вам нужно каким-то образом ввести начальное значение, после этого оно совершенно детерминировано.

4. Я бы попытался PromptT оснастить RVarT MFunctor and PrimMonad экземплярами and (нет очевидных препятствий), а затем hoist lift ranfu into RVarT ST .

Ответ №1:

Вероятно, самый простой способ — использовать RandomSource экземпляр для ST in Data.Random.Source.MWC :

 import Data.Random.Source.MWC

sample :: [Bool]
sample = runST $ do
  g <- create
  stTrav (i -> runRVar ranfu g)