【Haskell】 Stateモナドで乱数生成用モジュールを作る
今日もHaskellネタ。
Haskellでは避けて通れないモナドの話をしてみようと思ったのですが
・・・やっぱり難しい。
結局のところ、
だよなぁと思ったので、モナドについて解説するのはやめにして、 実際にモナドを使ったコードを書いてみます。
Stateモナドを使った、簡単な乱数ライブラリ
使い方
ソースコード
module EasyRandom (
Random(..),
random,
uniform,
permutation,
normal,
runRandom
) where
import Control.Monad.State.Lazy
(state, State(..), runState)
import qualified System.Random as R
(random, randomR, getStdRandom, StdGen(..), Random)
import qualified Data.Random.Normal as N
(normal)
type Random a = State R.StdGen a
random :: Random Int
random = state R.random
normal :: Random Double
normal = state N.normal
constant :: a -> Random a
constant = return
uniform :: R.Random a => (a, a) -> Random a
uniform (x,y) = state $ R.randomR (x,y)
permutation :: [a] -> Random [a]
permutation ls = permutation' (length ls) ls
permutation' :: Int -> [a] -> Random [a]
permutation' _ = return
permutation' _ [x] = return [x]
permutation' n (x:xs) = do
ys <- permutation' (n - 1) xs
i <- uniform (0, n - 2)
return (ys !! i) : update i x ys
where
update :: Int -> a -> [a] -> [a]
update i x xs
| i < 0 = xs
| otherwise = let (ls, (r:rs)) = splitAt i xs in ls ++ (x:rs)
runRandom :: Random a -> IO a
runRandom = R.getStdRandom . runState
以上です(汗)