寄り道ついでに Random モジュールも覗いてみた。乱数はゲームを作ったり、シミュレーションをしたりするときに必須なので、Haskell での作り方を知っておいて損はない。
ghci で乱数を試すときは、まず Random モジュールをインポートする必要がある。 Prelude> :m Random Prelude Random> 乱数はシード値という数値を元に、演算で作成する。Haskell の場合デフォルトのシード値があり、getStdGen で取り出すことができる。 Prelude Random> getStdGen 486513661 1 このシード値を元に乱数を発生させるわけだが、それには、getStdRandom 関数を使う、この関数は引数に random 関数または randomR 関数をとり乱数を発生させることができる。シード値は暗黙に利用されるので引数には現れない。 getStdRandom 関数が random 関数を引数に取ると、範囲指定のない整数値の乱数を発生させる。 Prelude Random> getStdRandom random -134536735 Prelude Random> getStdRandom random -929791202 getStdRandom 関数が randomR 関数を引数にとると、範囲指定のある乱数を発生させることができる。randomR 関数は数値のペアを引数にできるが、整数値のペアの場合乱数は整数値が発生する。 Prelude Random> getStdRandom (randomR (1, 6)) 1 Prelude Random> getStdRandom (randomR (1, 6)) 3 randomR 関数の引数が実数値のペアの場合、実数値の乱数を getStdRandom 関数で発生させることができる。 Prelude Random> getStdRandom (randomR (0.0, 1.0)) 0.6565188367749841 Prelude Random> getStdRandom (randomR (0.0, 1.0)) 0.5448677856579581 また、乱数の無限リストを発生させる関数があり、randoms は範囲指定のない乱数の無限リストを、randomRs は範囲指定のある乱数の無限リストを発生させる。 randoms は引数にシード値をとる。シード値は getStdGen で取得することができるが、getStdGen の戻値は IO モナド型なので、そのままでは使えない。シード値を取り込む関数を1引数IO a型戻値の IO モナド型関数にしておいて、>>= 演算子で注ぎ込まないといけない。 Prelude Random> getStdGen >>= return . (take 3) . randoms [-1346026573,-1375852214,106540112] あるいは、do 記法をつかうと、もう少し分かりやすいかもしれない。 Prelude Random> do rand <- getStdGen; return (take 3 (randoms rand)) [-1346026573,-1375852214,106540112] 同様に randomRs を使って範囲指定のある乱数のリストを発生させるには次のようにする。 Prelude Random> getStdGen >>= return . (take 3) . (randomRs (1, 6)) [6,4,1] Prelude Random> do rand <- getStdGen; return (take 3 (randomRs (1, 6) rand)) [6,4,1] シード値を変更したい時は newStdGen 関数を使う。 Prelude Random> newStdGen 429156803 1336516155 Prelude Random> newStdGen 429196817 498340276 Prelude Random> newStdGen >>= return . (take 3) . (randomRs (1, 6)) [1,6,2] これで乱数の作り方は分かったが、作成された乱数は IO a 型で戻されるのでそのままでは使えない。乱数を利用する方も1引数 IO a 型戻値の IO モナド型関数にしなければならないので注意が必要だ。 サイコロを振って3より大きければ勝ちで、3以下なら負けとなるプログラムを作ってみよう。最初は do 記法で。 Prelude Random> do score <- getStdRandom (randomR (1, 6)); return (if score > 3 then "you win" else "you loose") "you loose" >>= 演算子を使うとこうなる。 Prelude Random> getStdRandom (randomR (1, 6)) >>= return . (\x -> if x > 3 then "you win" else "you loose") "you loose" どうやっても、負けてしまった。
by tnomura9
| 2011-08-17 19:46
| Haskell
|
Comments(0)
|
カテゴリ
新型コロナウイルス 主インデックス Haskell 記事リスト 圏論記事リスト 考えるということのリスト 考えるということ ラッセルのパラドックス Haskell Prelude Ocaml ボーカロイド 圏論 jQuery デモ HTML Python ツールボックス XAMPP Ruby ubuntu WordPress 脳の話 話のネタ リンク 幸福論 キリスト教 心の話 メモ 電子カルテ Dojo JavaScript C# NetWalker ed と sed HTML Raspberry Pi C 言語 命題論理 以前の記事
最新のトラックバック
最新のコメント
ファン
記事ランキング
ブログジャンル
画像一覧
|
ファン申請 |
||