2012-02-13 4 views
9

Может ли кто-нибудь предоставить пример «для-манекенов», как использовать «MonadRandom»?Как пользоваться MonadRandom?

В настоящее время у меня есть код, который делает такие вещи, как огибают переменной генератора, весь путь от главной функции:

main = do 
    g <- getStdGen 
    r <- myFunc g 
    putStrLn "Result is : " ++ show r 

--my complicated func 
myFunc g x y z = afunc g x y z 
afunc g x y z = bfunc g x y 
bfunc g x y = cfunc g x 
cfunc g x = ret where 
     (ret, _) = randomR (0.0, 1.0) g 

Thanks

ответ

13

В принципе все дополнительные параметры g можно просто отбросить. Затем вы получаете случайные числа, используя функции от Control.Monad.Random (например, getRandomR). Вот ваш пример (я добавил некоторые аргументы, чтобы сделать его компиляции):

import Control.Monad.Random 

main = do 
    g <- getStdGen 
    let r = evalRand (myFunc 1 2 3) g :: Double 
    -- or use runRand if you want to do more random stuff: 
    -- let (r,g') = runRand (myFunc 1 2 3) g :: (Double,StdGen) 
    putStrLn $ "Result is : " ++ show r 

--my complicated func 
myFunc x y z = afunc x y z 
afunc x y z = bfunc x y 
bfunc x y = cfunc x 
cfunc x = do 
    ret <- getRandomR (0.0,1.0) 
    return ret 
+0

Я думаю, что у вас 'runRand' и' evalRand' перепутаны! – dflemstr

+0

Не знаете, как это произошло, так как я запустил код :) Исправлено. – porges

+0

Конечно, 'myFunc',' aFunc', 'bFunc' и' cFunc' теперь являются монадическими. Они возвращают значения, завернутые в монаду «Rand», которые должны быть извлечены с помощью '>> =' (или '<-' в' do') и созданы с помощью 'return'. – pat

7

Вы просто запустить что-то в RandT монады трансформатора с runRandT или evalRandT и для чистого Rand монады, с runRand или evalRand:

main = do 
    g <- getStdGen 
    r = evalRand twoEliteNumbers g 
    putStrLn $ "Result is: " ++ show r 

twoEliteNumbers :: (RandomGen g) => Rand g (Double, Double) 
twoEliteNumbers = do 
    -- You can call other functions in the Rand monad 
    number1 <- eliteNumber 
    number2 <- eliteNumber 
    return $ (number1, number2) 

eliteNumber :: (RandomGen g) => Rand g Double 
eliteNumber = do 
    -- When you need random numbers, just call the getRandom* functions 
    randomNumber <- getRandomR (0.0, 1.0) 
    return $ randomNumber * 1337 
+0

Мм ... но это не ваш 'func' работает внутри' IO' или монады? – drozzy

+0

Также ... что произойдет, если я позвоню 'func' не из main? – drozzy

+0

'do' не означает, что вы используете монаду IO. Я использую монаду «Ранд» здесь. – dflemstr

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