<   2015年 01月 ( 9 )   > この月の画像一覧

Siri との会話

Siri との会話のリンク集

日本語Siriさんとのすごい会話

「イライザって誰?」Siriに聞いたら不思議な答えが返ってくるんだけど…

【笑える】面白すぎる「Siri」のびっくりするやりとりiPhone(日本語版)おもしろ【Apple】

iPhone【Siri】会話がもはや感動モノ。いろんな意味で泣かされる【随時更新】

siriとの会話にハマる人続出!!厳選した面白会話集をご紹介♪♪

【siri攻略】iPhoneのsiriからプロポーズOKをもらうためにやった8つの挑戦

もちろん Siri が言われたことを理解して答えているわけではないだろう。こういうパターンの問に対する答えのリストが存在して、その中からランダムに選んでいるに違いない。しかし、将来的にはしっかりと言葉を理解して答えてくれるプログラムが出現するかもしれない。そのときに、そのプログラムに依存してしまう人間が出てくるかもしれないと思うと怖いような気がする。

しかし、人間の女子高生の会話のほうがぶっとんでいる。やはり人間、楽しい。

女子高生のハイレベルすぎる会話にタジタジ……爆笑10選!!
[PR]
by tnomura9 | 2015-01-14 18:50 | 話のネタ | Comments(0)

System.Random (6) Haddock

Haddock User GuidChapter 3. Documentation and Markup (文書の仕様とマークアップ)

3.4. Controlling the documentation structure

この節では Haskell のソースコードの Haddock 文書を作る時、記述する entity の順序を変更するための工夫について延べてある。このことで、プログラマーは作成する entity の順序をあまり考えずにプログラムを作った後、Haddock 文書にするときに、記述する entity の順序を関連性に応じて自由に変更できる。

これは、モジュールの export list の中で行われる。つぎの例では module Foo の文書の内容の構成がモジュールのエクスポート・リストの中に記述されている。

module Foo (
  -- * Classes
  C(..),
  -- * Types
  -- ** A data type
  T,
  -- ** A record
  R,
  -- * Some functions
  f, g
  ) where

このようにすると、作成された Haddock の構成は次のようになる。

Module Foo
  Classes
    C(..)
  Types
    A data type
      T
    A record
      R
  Some functions
    f, g

--* や --** で entity のヘッダーの階層のレベルを変えることができる。

実際の例として、Hackage の System.Random のHTML 文書をそのソースコードと比較してみる。

ソースコードのモジュールのエクスポートリストは次のようになっている。

module System.Random
      (

      -- $intro

      -- * Random number generators

        RandomGen(next, split, genRange)

      -- ** Standard random number generators
      , StdGen
      , mkStdGen

      -- ** The global random number generator

      -- $globalrng

      , getStdRandom
      , getStdGen
      , setStdGen
      , newStdGen

      -- * Random values of various types
      , Random ( random,   randomR,
               randoms,  randomRs,
               randomIO, randomRIO )

      -- * References
      -- $references

      ) where

これは System.Random の Haddock 文書の記述の順序と同じである。また、エクスポートリストの中のコメントのタイトルは、そのまま目次となって HTML 文書の右肩に表示される。

また、リスト中の $references はチャンクといって、他のコメントの塊に名前をつけたものである。Haddock 文書にはこの名前の部分が元のコメントに置き換えられる。System.Random の場合、$references の部分は次の内容に置き換えられる。

{- $references

1. FW #Burton# Burton and RL Page, /Distributed random number generation/,
Journal of Functional Programming, 2(2):203-212, April 1992.

2. SK #Park# Park, and KW Miller, /Random number generators -
good ones are hard to find/, Comm ACM 31(10), Oct 1988, pp1192-1201.

3. DG #Carta# Carta, /Two fast implementations of the minimal standard
random number generator/, Comm ACM, 33(1), Jan 1990, pp87-88.

4. P #Hellekalek# Hellekalek, /Don\'t trust parallel Monte Carlo/,
Department of Mathematics, University of Salzburg,
<http://random.mat.sbg.ac.at/~peter/pads98.ps>, 1998.

5. Pierre #LEcuyer# L'Ecuyer, /Efficient and portable combined random
number generators/, Comm ACM, 31(6), Jun 1988, pp742-749.

The Web site <http://random.mat.sbg.ac.at/> is a great source of information.

-}

3.5. Named chunks of documentation

この節では named chunk (名前付きチャンク)について解説されている。チャンクとは英語でチーズやパンの塊のことである。A chunk of bread のような使い方をする。注釈の塊に名前をつけて、エクスポートリストの中で置き換えて使うというのが目的のようだ。上の例でも $references のような named chunk が使われていた。用例としては次のようなものが基本だ。

module Foo (
      -- * A section heading

      -- $doc
      ...
 ) where

-- $doc
-- Here is a large chunk of documentation which may be referred to by
-- the name $doc.
[PR]
by tnomura9 | 2015-01-12 18:33 | Haskell | Comments(0)

System.Random (5) Haddock

Haddock User Guid の Chapter 3. Documentation and Markup (文書の仕様とマークアップ)

この章では、Haddock 文書を作成するときの説明文書の作り方や、マークアップの方法を延べてある。System.Random モジュールのソース解読が目的なので、ここでは、System.Random を解読できる程度の要素をピックアップする。

3.1. Documenting a top-level declaration

このセクションでは、top-level の宣言(関数のタイプの宣言や、型の宣言、型クラスの宣言など)につける注釈の記入の仕方を説明してある。この注釈は、Haddock では基本的なもので頻出する。例えば、

square :: Int -> Int
square x = x * x

という関数が宣言されていた時、これに対する説明は、Haskell のコメント記号 -- のあとに | をつけて、次のように記入する。

-- |The 'square' function squares an integer.
square :: Int -> Int
square x = x * x

実際の例として、Hackage の System.Random のHTML 文書をそのソースコードと比較してみる。

System.Random のソースコードを読むと、class RandomGen g where という RandomGen 型クラスの宣言の上に -- | の後に RandomGen クラスの注釈が書いてあるが、

-- | The class 'RandomGen' provides a common interface to random number
-- generators.
--
-- Minimal complete definition: 'next' and 'split'.

class RandomGen g where

これを Hackage の System.Random の Haddock 文書で見ると次のように記述されている。

class RandomGen g whereSource

    The class RandomGen provides a common interface to random number generators.

    Minimal complete definition: next and split.

Hackage の System.Random の文書とそのソースコードを比べてみると、この注釈と宣言の関係が数多く見られるのがわかる。この Haskell の entity に注釈をつけるやり方が Haddock の基本であることが分かる。したがって、-- コメントの記述のみの場合は、このコメントは Haddock 文書に反映されず隠蔽できる。

-- | は宣言文の前にコメントを置く場合に使用されるが、--^ はコメントを宣言文の後に記述する場合に -- | と同じ意味を持たせることができる。しかし、ここでは詳細は省略する。

3.2. Documenting parts of a declaration

この節では、クラスメソッドや、コンストラクタとそのフィールド、関数の引数などに Haddock のコメントを付ける方法が説明されているが、基本的には上の例と同じ意味であるので説明を省略する。

3.3. The module description

ここでは、モジュール全体についての説明の書き方を説明してある。モジュール全体については、Module, Description, Copyright, License, Maintainer, Stability, Portability などのどのモジュールにも共通のキーワードがあるので、Haddock ではそれを抽出して特別に表示する。

この注釈はソースコードの冒頭に置かれている。

System.Random の冒頭は次のようになっているが、

-----------------------------------------------------------------------------
-- |
-- Module      :  System.Random
-- Copyright   :  (c) The University of Glasgow 2001
-- License     :  BSD-style (see the file libraries/base/LICENSE)
--
-- Maintainer  :  libraries@haskell.org
-- Stability   :  stable
-- Portability :  portable
--
-- This library deals with the common task of pseudo-random number
-- generation. The library makes it possible to generate repeatable
-- results, by starting with a specified initial random number generator,
-- or to get different results on each run by using the system-initialised
-- generator or by supplying a seed from some other source.
--
-- The library is split into two layers:
--
-- * A core /random number generator/ provides a supply of bits.
--   The class 'RandomGen' provides a common interface to such generators.
--   The library provides one instance of 'RandomGen', the abstract
--   data type 'StdGen'.  Programmers may, of course, supply their own
--   instances of 'RandomGen'.
--
-- * The class 'Random' provides a way to extract values of a particular
--   type from a random number generator.  For example, the 'Float'
--   instance of 'Random' allows one to generate random values of type
--   'Float'.
--
-- This implementation uses the Portable Combined Generator of L'Ecuyer
-- ["System.Random\#LEcuyer"] for 32-bit computers, transliterated by
-- Lennart Augustsson.  It has a period of roughly 2.30584e18.
--
-----------------------------------------------------------------------------

Hackage の System.Random 文書の右上の部分を見ると、キーワードの内容が抽出されて、それぞれ表示されているのが分かる。注釈の先頭の行の冒頭にある -- | に注目して欲しい。Haddock 文書に反映される注釈は全て -- | で始まることが分かる。

こうしてみると、Hackage の Haskell のモジュールについての文書の内容が、モジュールのソースコードに密着しているのがわかる。また、HTML 文書からソースコードへはハイパーリンクで簡単にアクセスできるので、Haskell のモジュールのソースコードの解読は、Hackage の Haddock 文書からスタートすれば十分であることが分かる。
[PR]
by tnomura9 | 2015-01-12 15:06 | Haskell | Comments(0)

System.Random (4) Haddock

Haddock User GuidChapter 2. Invoking Haddock (Haddock の起動)

Haddock はコマンド・ラインから次のようにして起動する。

haddock [option...] file

fileは 拡張子が .hs の Haskell のモジュールのソースファイルを指定する。また、Haskell のソースコードが文書の中に > 記号で埋め込まれた literate Haskell source module で拡張子が .lhs のものも指定できる。

コマンド・ラインに並べられた全てのファイルについては、一緒にコンパイルできる。あるモジュールのプログラムの部品(entity)が、他のモジュールの entity を参照していた時は、作成される文書にその entity へのリンクが作成される。

参照した entity が見つからなかった時、このような場合は参照したモジュールのソースファイルがコマンド・ラインで指定されていなかった時などに起きるが、単純にリンクが作成されないだけである。この場合 Haddock は参照できなかった entity のリストを警告と一緒に出力する。

モジュールの entity は相互参照してはならない。Haddock の処理が無限ループに陥らないためである。

Haddock の古いバージョンに準拠したマークアップがソースコードに記述されている時は、このようなファイルを新しいバージョンの Haddock で処理するとエラーになる。パースエラーのメッセージがでた場合は、レポートして欲しい。

ファイルの指定以外には、出力の形式を指定するオプションが必要である。現在のバージョンでは、-h オプションは HTML 文書を出力し、--hoogle オプションは Hoogle のデータを出力する。

パッケージ作成ツールの Cabal は Haddock をサポートしている。そのため、Haddock を直接起動しなくてもモジュールの文書作成ができる。

オプションには以下の様なものが利用できる。

-B dir
dir で GHC の lib directory を指定する。これによって、default path を上書きできる。
-o dir, --odir=dir
文書の出力を dir に変更できる。デフォールトは current directory
-l dir, --lib=dir
Haddock の補助的なファイル(themes, javascript, etc...)について dir のものを利用する。
-i path, file, --read-interface=path,file
file に指定したインターフェースファイルを使用する。Haddock を -dump-interface オプションで作動した時にインターフェースファイルも作成される。このファイルにはモジュールの HTML 文書が置かれている path の名前が書かれている。path は相対パスも可能である。path の指定はオプショナルで、デフォールトは "." である。

このオプションを使うことによって、所在の異なる文書セットにハイパーリンクを張ることができる。path の示すパスには正確にこれらの文書セットが収めてある必要がある。したがって、後で HTML 文書の位置を移動するとハイパーリンクが壊れてしまう。path に相対パスを利用すれば、HTML 文書の移動が可能になる。

--read-interface オプションは複数指定できる。
-D file, --dump-interface=file
file で指定するファイル名でインターフェースファイルを作成する。インターフェースファイルに作成される情報は、コマンド・ラインで指定したモジュール以外のモジュールを参照するときに必要である。詳細は --read-interaface オプションの項を参照。インターフェースファイルはバイナリなので読むことはできない。
-h, --html
HTML 形式の文書を出力する。複数のファイルが current directory か -o オプションで指定されたディレクトリに作成される。

module.html,mini_module.html
個々のモジュールの HTML ページ。mini ページはフレームを利用するときの HTML 文書。
index.html
トップレベルの HTML 文書。利用可能なモジュールやモジュール間の階層構造を表示する。
doc-index.html, doc-index-X.html
索引の文書。項目が多い時は複数のページに分割される。
frames.html
トップレベルの文書をフレームで見るための文書。
haddock-util.js
セクションの細部を隠したり、フレームビューを切り替えたりするための JavaScript ファイル。
--source-base=URL, --source-module=URL, --source-entity=URL, --source-entity-line=URL
モジュールの文書作成次のソースファイルへのリンクを指示する。--source-base オプションを指定すると、ヘッダーバーとインデックスページにソースコードへのリンクを張ることができる。--source-module オプションを使うと、モジュールページのヘッダーにソースコードへのリンクが張れる。--souruce-entity オプションを指定すると、ソースコードへのリンクを文書のそれぞれの値やタイプの横に張る。--source-entity-line オプションではソースの正確な場所にリンクを張れる。(以下意味が不明だった。eg. since they were definside a Template Haskell splice)
上のオプションのいずれの場合にも 変数によるURLの置き換えができる。(個々のルールの意味がわからなかったので以下原文。)

  • The string %M or %{MODULE} is replaced by the module name. Note that for the per-entity URLs this is the name of the exporting module.
  • The string %F or %{FILE} is replaced by the original source file name. Note that for the per-entity URLs this is the name of the defining module.
  • The string %N or %{NAME} is replaced by the name of the exported value or type. This is only valid for the --source-entity option.
  • The string %K or %{KIND} is replaced by a flag indicating whether the exported name is a value 'v' or a type 't'. This is only valid for the --source-entity option.
  • The string %L or %{LINE} is replaced by the number of the line where the exported value or type is defined. This is only valid for the --source-entity option.
  • The string %% is replaced by %.


さしあたって、HTML文書を Haddock で作成するために必要そうなオプションだけをピックアップした。これらのオプションでできることは、ソースコードから HTML 文書を作成すること。異なるモジュール間のハイパーリンクを自動的に作成すること、HTML 文書からソースコードへのリンクを作成することなどだ。

実際に Haddock を使って文書を作成するときは、冒頭のリンクの文書を熟読する必要があるだろう。
[PR]
by tnomura9 | 2015-01-11 17:53 | Haskell | Comments(0)

Siri

iPhone の Siri に「おみくじ」というと「中吉です」などと占ってくれるらしい。

面白そうなので、子供に頼んで Siri に "I love you" と言ってもらったら、

" You can't"

という返事が帰ってきた。これって「ダメよ、ダメ、ダメ」じゃないかと思って面白くなったので、どうせ、他の人も同じようなことをしているのだろうと思ってググってみたらあった。次のような会話になるようだ。

"I love you"

"You hardly know me"

"I love you"

"You can't"

"I love you"

"I hope you don't say that to those other mobile phones"

"I love you"

"Oh, I bet you say that to all your Apple products"

なんか Siri に恋してしまいそうになった。
[PR]
by tnomura9 | 2015-01-07 09:53 | 話のネタ | Comments(0)

System.Random (3) Haddock

Haddock User Guide の第1章 Introduction (概要) の日本語抄訳を作った。

1. Introduction (概要)

Haddock は Haskell のソースから API に関する文書を作成するためのプログラムである。Haddock の仕様は以下のことを念頭に作成されている。

  • API についての文書と実際の API の動作の解離を防ぐため、生のコードから関数や、タイプ、クラスなどの実体の情報を直接に取り出している。
  • Haddock は生の Haskell 98 のモジュールの全セットから文書を作り出せる。
  • Haddock はソースのコメントに iDoc に類似した簡易マークアップを導入している。
  • Haddock の文書はモジュールの export しない部分については表示しないようにできる。
  • Haddock では文書間のハイパーリンクを自動的に作成できる。
  • Haddock では、ソースコードは HTML, LaTex, Hoogle などの色々な文書に変換できる。また、その他のフォーマットが簡単に追加できるように構造化されている。

1. Introduction ではこの冒頭の説明の後で、以下のセクションが続いているが、Haddock 自体が Haskell Platform に標準で装備されているので読解は省略する。

1.1. Obtaining Haddock
1.2. License
1.3. Contributors
1.4. Acknowledgements
[PR]
by tnomura9 | 2015-01-05 21:04 | Haskell | Comments(0)

System.Random (2) Haddock

A. Haddock について

System.Random のソースの大半を占めているのは、コード本体ではなくてコメントだ。それは、コード本体とその説明書が一致しなくなるのを防ぐためだ。コードとその説明が一体となっていれば、それが可能だ。

しかし、コメントだけを読んででいくのは少々しんどい。説明の文書の構造などをコメントだけで表現するのは難しいからだ。そこで、Haddock ではコメントに簡単なマークアップ言語を仕込めるようになっている。マークアップされたコメントを含むソースプログラムからは、haddock コマンドを利用することによって、HTML文書などに変換することができる。

このように Haskell のコードを読む努力の多くが、埋め込まれたコードの説明の解読に費やされるため、遠回りだが、Haddock の仕様について知っておく必要がある。

B. Haddock User Guide

Haddock についての文書は Haddock User Guid にアクセスすれば読むことができる。Haddock User Guide の目次は次のようになる。

Table of Contents

1. Introduction

    1.1. Obtaining Haddock
    1.2. License
    1.3. Contributors
    1.4. Acknowledgements

2. Invoking Haddock

    2.1. Using literate or pre-processed source

3. Documentation and Markup

    3.1. Documenting a top-level declaration
    3.2. Documenting parts of a declaration

        3.2.1. Class methods
        3.2.2. Constructors and record fields
        3.2.3. Function arguments

    3.3. The module description
    3.4. Controlling the documentation structure

        3.4.1. Re-exporting an entire module
        3.4.2. Omitting the export list

    3.5. Named chunks of documentation
    3.6. Hyperlinking and re-exported entities
    3.7. Module Attributes
    3.8. Markup

        3.8.1. Paragraphs
        3.8.2. Special characters
        3.8.3. Character references
        3.8.4. Code Blocks
        3.8.5. Examples
        3.8.6. Properties
        3.8.7. Hyperlinked Identifiers
        3.8.8. Emphasis, Bold and Monospaced text
        3.8.9. Linking to modules
        3.8.10. Itemized and Enumerated lists
        3.8.11. Definition lists
        3.8.12. URLs
        3.8.13. Images
        3.8.14. Anchors
        3.8.15. Headings

結構大部だが、ざっとみると第1章が概要(introduction)、第2章がコマンド・ラインからの haddock の使い方 (invoking Haddock)、第3章がソースに作成する文書のマークアップについての説明 (Documentation and Markup) になっている。

次回からこれらについて一つづつ読解していくことにする。面倒だが Haskell Platform のモジュールのソースを読解する上で Haddock についての知識は必須だ。コメントの文書化だけでなく、ソース本体の文書化にも関係してくるからだ。
[PR]
by tnomura9 | 2015-01-04 15:01 | Haskell | Comments(0)

System.Random (1)

System.Random モジュールを import して乱数を作ってみているうちに、このモジュールなら解読するのに丁度いい大きさではないかと思いついた。

そこで Google で「 Hackage System.Random 」で検索した所、System.Random の Haddock 文書が見つかった。

Hackage の System.Random の Haddock 文書

Hackage の Haddock 文書は見出しの行の右端の source リンクをクリックするとプログラムのソースを表示させることができる。

System.Random のソース

Haddock 文書とソースを見比べてみたら、当然だが、Haddock文書とソースのコメントは全く一致していた。

そうであれば、このソースから haddock を使ってHTMLで書かれたマニュアルが作成できるのではないだろうかと思いついた。

そこで、まず random というディレクトリを作成して、ノートパッドで Random.hs というファイルを作り上で調べた System.Random のソースをコピペした。

C:\Users\********\Haskell>mkdir random

C:\Users\********\Haskell>cd random

C:\Users\********\Haskell\random>notepad Random.hs

C:\Users\********\Haskell\random>dir

2015/01/03 23:58 15,067 Random.hs

この Random.hs を元に Haddock の HTML 文書を作成しようとしたが、字句解析エラーになってしまった。

C:\Users\********\Haskell\random>haddock -h Random.hs

Random.hs:74:2: lexical error at character 'i'

そこで、ソースを再度読んでみたら、エラーの場所は #ifdef と記述のあるプリプロセッサのディレクティブのある箇所だった。

#ifdef __NHC__
import CPUTime( getCPUTime )
import Foreign.Ptr ( Ptr, nullPtr )
import Foreign.C( CTime, CUInt )
#else
import System.CPUTime( getCPUTime )
import System.Time( getClockTime, ClockTime(..) )
#endif

これは nhc98 というコンパイラを使用している場合の条件コンパイルのためのディレクティブだ。そこで、この部分を削除した。同様のプリプロセッサに関する部分はもう1箇所あったので、それも nhc98 に関係する部分を削除し、また #ifdef, #else, #endif などのディレクティブのある行も削除した。

そこで、再度 haddock -h Random.hs を実行した。

C:\Users\********\Haskell\random>haddock -h Random.hs
Haddock coverage:
Cannot find documentation for: $intro
100% ( 16 / 16) in 'System.Random'
Warning: System.Random: could not find link destinations for:
GHC.Types.Int GHC.Show.Show GHC.Read.Read Text.Read.read GHC.Show.show GHC.T
ypes.IO GHC.Enum.Bounded GHC.Types.Char GHC.Integer.Type.Integer GHC.Types.Bool
GHC.Types.Double GHC.Types.Float

エラーメッセージがでたが、ディレクトリの中をみたらたくさんの文書が作成されていた。

C:\Users\********\Haskell\random>dir

2015/01/04 00:12 2,926 doc-index.html
2015/01/04 00:12 860 frames.html
2015/01/04 00:12 8,189 haddock-util.js
2015/01/04 00:12 1,684 hslogo-16.png
2015/01/04 00:12 680 index-frames.html
2015/01/04 00:12 1,132 index.html
2015/01/04 00:12 1,795 mini_System-Random.html
2015/01/04 00:12 56 minus.gif
2015/01/04 00:12 8,651 ocean.css
2015/01/04 00:12 59 plus.gif
2015/01/04 00:12 14,691 Random.hs
2015/01/04 00:12 11,327 synopsis.png
2015/01/04 00:12 19,155 System-Random.html
13 個のファイル 71,205 バイト

そこで、次のように Firefox でファイルを開いてみたら System.Random についての HTML 文書を表示できた。

C:\Users\********\Haskell\random>"C:\Program Files\Mozilla Firefox\firefox.exe" index.html

ソースへのリンクは作成されていなかったが、index.html 以下の文書が確かに Random.hs についての HTML 文書になっていることが分かった。したがって、System.Random モジュールの全てのソースはコピペした Random.hs に含まれていることがわかった。
[PR]
by tnomura9 | 2015-01-04 00:30 | Haskell | Comments(0)

Haskell で乱数

1. System.Random モジュール

Haskell で乱数を使うには、System.Random モジュールをインポートする。

Prelude> import System.Random
Prelude System.Random>

2. Random クラス

Random クラスで使える関数は次のようになる。

Prelude System.Random> :i Random
class Random a where
  randomR :: RandomGen g => (a, a) -> g -> (a, g)
  random :: RandomGen g => g -> (a, g)
  randomRs :: RandomGen g => (a, a) -> g -> [a]
  randoms :: RandomGen g => g -> [a]
  randomRIO :: (a, a) -> IO a
  randomIO :: IO a
        -- Defined in ‘System.Random’
instance Random Integer -- Defined in ‘System.Random’
instance Random Int -- Defined in ‘System.Random’
instance Random Float -- Defined in ‘System.Random’
instance Random Double -- Defined in ‘System.Random’
instance Random Char -- Defined in ‘System.Random’
instance Random Bool -- Defined in ‘System.Random’

Int, Double, Char, Bool などが Random クラスのインスタンス宣言されているので、これらの乱数をおなじ random や randomR 関数などで発生させることができるが、これについては後で述べる。

3. 乱数発生器 (random number generator)

乱数を発生させるためには StdGen 型の乱数発生器を作成することが必要だが、StdGen のパラメータは 32bit の2つの整数からなっている。

Prelude System.Random> :i StdGen
data StdGen = System.Random.StdGen GHC.Int.Int32 GHC.Int.Int32
        -- Defined in ‘System.Random’
instance Read StdGen -- Defined in ‘System.Random’
instance Show StdGen -- Defined in ‘System.Random’
instance RandomGen StdGen -- Defined in ‘System.Random’

mkStdGen 関数を使うと乱数のシードとなる整数から StdGen 型の値を作ることができる。

Prelude System.Random> mkStdGen 7
8 1

また、getStdGen 関数を使うと、コンピュータの内部の数値を使って StdGen を作ることができるが、これは IO StdGen 型になる。

Prelude System.Random> :t getStdGen
getStdGen :: IO StdGen
Prelude System.Random> getStdGen
1040244465 525453832

4. random 関数と randomR 関数

random や randomR を使って乱数を発生させるときは、上の方法で作成した乱数発生器が必要だ。

Prelude System.Random> random (mkStdGen 7)
(5400045519604638010,33684305 2103410263)
Prelude System.Random> randomR (1,6) (mkStdGen 7)
(6,320112 40692)

random の戻り値は (Int, StgGen) のペアが返される。次の乱数を発生するには戻された StdGen を利用して新しい値を発生する。randomR は第1引数で乱数の範囲を指定することができる。

random や randomR で実数型の乱数を作成するには戻り値の型指定をする。

Prelude System.Random> randomR (1,6) (mkStdGen 7) :: (Double, StdGen)
(3.6274349444931353,33684305 2103410263)

5. randoms 関数と randomRs 関数

random 関数と randomR 関数を使う方法が基本的な乱数の発生方法だが、randoms や randomRs 関数を使うと簡単に乱数のリストを発生させることができる。これらで発生されるのは無限リストなので take 関数で必要な数を取り出す。

Prelude System.Random> take 10 $ randomRs (1,6) (mkStdGen 7)
[6,1,4,5,3,2,3,6,6,6]

実数の乱数のリストが必要な場合は次のようにする。

Prelude System.Random> take 10 $ randomRs (1,6) (mkStdGen 7) :: [Double]
[3.6274349444931353,3.7195766207205945,2.4670708412037783,1.1496465237766436,4.7616565380048606,1.5249116853564635,4.932441237453773,1.5817653765782904,3.020767690217343,4.271546198074163]

文字列の乱数リストも発生できる。

Prelude System.Random> take 10 $ randomRs ('a', 'd') (mkStdGen 7)
"bcbacbcddb"

Bool 値の乱数リストもできる。

Prelude System.Random> take 10 $ randoms (mkStdGen 7) :: [Bool]
[True,False,True,False,False,True,False,True,True,True]

6. randomIO 関数と randomRIO 関数

ゲームの時のようにプログラムの実行時に乱数を発生させる必要があるときは、randomIO や randomRIO 関数を用いるが、これらは関数を呼び出すだけで IO a 型の乱数を得ることができるので簡単だ。

Prelude System.Random> :t randomIO
randomIO :: Random a => IO a
Prelude System.Random> randomIO
7568657320075196309
Prelude System.Random> randomIO
4695944892596501485

実数の乱数が欲しい場合には次のようにする。

Prelude System.Random> randomRIO (1,6) :: IO Double
5.801705368416644

これらの値は IO a 型なので IO モナドの中で使う必要がある。

Prelude System.Random> do x <- randomRIO (1,6); return (x, 2 * x)
(3,6)

Haskell で乱数を使うのはややこしそうに見えるが、random 関数や ranndomR 関数で乱数発生器の値を引数にして乱数を発生することや、戻り値の型を指定をすることでいろいろな型の乱数を発生できることが分かれば、これまでの例を自分で実行してみることで簡単に使えるようになる。

7. 参考サイト

お気楽 Haskell プログラミング入門

追記

乱数発生器 (StdGen 型)のデータは Show クラスと Read クラスのインスタンスなので RandomGen 型のデータを文字列にしたり、文字列を StdGen 型のデータにしたりできる。

Prelude System.Random> return (show (mkStdGen 7))
"8 1"

Prelude System.Random> read "123 456" :: StdGen
123 456
[PR]
by tnomura9 | 2015-01-03 12:42 | Haskell | Comments(0)