2012-02-13 18 views
9

Czy ktoś może podać "for-dummies" przykład użycia `MonadRandom '?Jak korzystać z MonadRandom?

Obecnie mam kod, który robi takie rzeczy przechodząc wokół zmiennej generatora, całą drogę od głównej funkcji:

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

Odpowiedz

13

W zasadzie wszystkie dodatkowe parametry g można po prostu upuścić. Otrzymujesz losowe liczby używając funkcji z Control.Monad.Random (takich jak getRandomR). Oto twój przykład (dodałem kilka argumentów, aby go skompilować):

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

Myślę, że pomieszałeś 'runRand' i' evalRand'! – dflemstr

+0

Nie jestem pewien, jak to się stało, ponieważ uruchomiłem kod :) Naprawiono teraz. – porges

+0

Oczywiście, 'myFunc',' aFunc', 'bFunc' i' cFunc' są teraz monadyczne. Zwracają wartości zawinięte w monadę 'Rand', które muszą być wyodrębnione za pomocą' >> = '(lub' <-' w 'do') i utworzone za pomocą' return'. – pat

7

Wystarczy uruchomić coś w transformatorze RandT monady z runRandT lub evalRandT i dla czystego Rand monadzie z runRand lub 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

Um ... ale czy to nie jest twój "func" działający wewnątrz 'IO' lub monady? – drozzy

+0

Również ... co by się stało, gdybym nazwała 'func' nie z głównego? – drozzy

+0

'do' nie oznacza, że ​​używasz monady' IO'. Używam tutaj monadę 'Rand'. – dflemstr