#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
andPrimMonad
экземплярами and (нет очевидных препятствий), а затемhoist lift ranfu
intoRVarT 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)