如何使用MonadRandom?

And*_*yuk 13 haskell

有人可以提供"for-dummies"如何使用"MonadRandom"的例子吗?

目前我的代码可以执行诸如传递生成器变量之类的东西,从main函数一直到:

 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
Run Code Online (Sandbox Code Playgroud)

谢谢

por*_*ges 16

基本上所有额外的g参数都可以删除.然后使用Control.Monad.Random(例如getRandomR)中的函数获取随机数.这是你的例子(我添加了一些args以使其编译):

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
Run Code Online (Sandbox Code Playgroud)

  • 不,你可以在任何地方使用它们.你只需要使用带有`RandGen`参数的`evalRand`或`runRand`.基本上,你已经从明确地将参数传递给了'免费',而是在monad中工作.以这种方式犯错也更难(比如忘记传递`randomR`返回的第二个参数). (3认同)
  • 请记住,monadic并不表示`IO` monad。在这种情况下,我们谈论的是`Rand` monad。它可以确保生成器正确地通过了代码,因此您不会无意中从生成器的相同状态创建两个随机数(这会生成两个相同的所谓随机数)。在您的示例中,您将丢弃新的生成器。如果您想创建第二个随机数,可能会再次尝试使用`g`,但这是不正确的。 (2认同)

dfl*_*str 8

你只需在RandTmonad变换器中使用runRandTor 运行一些东西evalRandT,对于纯Randmonad,使用runRandevalRand:

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
Run Code Online (Sandbox Code Playgroud)