<   2015年 03月 ( 7 )   > この月の画像一覧

System.Random (14) StdGen -- Show クラス

System.Random 解読シリーズ

showsPrec

StdGen は RandomGen クラスのインスタンスだが、そのままでは ghci 上で値が表示されないので使い勝手が悪い。そこで、stdGen を文字列変換のためのクラス Show クラスのインスタンスにして、stdGen から 文字列への変換が定義されている。stdGen を Show クラスのインスタンスにするためのコードは次のようになっている。

instance Show StdGen where
  showsPrec p (StdGen s1 s2) =
     showsPrec p s1 .
     showChar ' ' .
     showsPrec p s2

このコードの showsPrec という関数の意味がわからないので ghci に尋ねてみる。

Prelude> :info showsPrec
class Show a where
  showsPrec :: Int -> a -> ShowS
  ...
        -- Defined in ‘GHC.Show’

どうやら GHC.Show というモジュールの関数らしい。GHC.Show モジュールの概要を ghci に尋ねた。

Prelude> :browse GHC.Show
class Show a where
  showsPrec :: Int -> a -> ShowS
  show :: a -> String
  showList :: [a] -> ShowS
type ShowS = String -> String
GHC.Show.appPrec :: Int
GHC.Show.appPrec1 :: Int
GHC.Show.asciiTab :: [String]
GHC.Show.intToDigit :: Int -> Char
GHC.Show.protectEsc :: (Char -> Bool) -> ShowS -> ShowS
showChar :: Char -> ShowS
GHC.Show.showList__ :: (a -> ShowS) -> [a] -> ShowS
GHC.Show.showLitChar :: Char -> ShowS
GHC.Show.showLitString :: String -> ShowS
GHC.Show.showMultiLineString :: String -> [String]
showParen :: Bool -> ShowS -> ShowS
GHC.Show.showSignedInt :: Int -> Int -> ShowS
GHC.Show.showSpace :: ShowS
showString :: String -> ShowS
shows :: Show a => a -> ShowS

showsPrec の型は Int -> a -> ShowS だ。ShowS はデータ型で String -> String だから、文字列を引数に取り、文字列を返す関数だ。showsPrec は ShowS 型の関数を戻値として返すようだ。showsPrec の二つの引数のうち、型変数 a のものは Show クラスのインスタンスのデータ型のデータだろうが、Int の意味がわからなかったので、Haskellのマニュアルを見てみたら次のようになっていた。

showsPrec
:: Int

the operator precedence of the enclosing context (a number from 0 to 11). Function application has precedence 10.
-> a

the value to be converted to a String
-> ShowS

Int 型の引数は演算の優先順位を表す 0 から 11 までの数のようだが、詳しい意味はわからなかった。しかし、この情報で showsPrec の動作をテストしてみることができる。

Prelude> showsPrec 0 10 " foo"
"10 foo"

Show クラスの show 関数には showsPrec が内部的に使われているが、show 関数は単に Show クラスのインスタンスのデータを文字列に変換するだけだ。

Prelude> show 10
"10"

この情報から StdGen の showsPrec のコードを見てみると、単に StdGen の二つのパラメータの整数をスペースで区切って表示しているだけだということが分かる。

StdGen は show 関数を直接定義するのではなく、showsPrec を定義することで間接的に show 関数を定義しているようだ。おそらく、show を直接に定義しないこのやり方がスタンダードで多分何か理由があるのだろうが、わからなかった。自前のデータ型を定義するときは、そのデータ型が Show 関数のインスタンスでないと ghci 上で評価して表示することができないのでデバッグが面倒になる。そのため自前のデータは Show クラスのインスタンスにすることが多いが、この例のように showsPrec 関数を定義すべきであることは頭に入れておくと良いのだろう。もちろん show 関数を直接に定義してもあまり問題はないようだ。
[PR]
by tnomura9 | 2015-03-28 23:47 | Haskell | Comments(0)

mai Uru

有名な youtuber らしい。線が細いが、丁寧な歌い方で、情感もこもっている。癒される音で何度でも聞き返したくなる。

I LOVE YOU  尾崎豊 (女性が歌うI LOVE YOU)  COVER by Uru

チャンネル

mai Uru
[PR]
by tnomura9 | 2015-03-27 10:19 | ボーカロイド | Comments(2)

考え続けること

サッカーの中田選手は基本練習を好んでやっていたらしい。まずボールの軌跡をイメージして、そのイメージ通りにボールを飛ばすためにはどういう風にボールを蹴ればいいかを工夫して飽きることがなかったという。

これと同じように、何か新しいことを習得しようとするときは、その事について考え続ける事が大切だ。昼も夜も暇があれはその事について考え続ける。

考え続けることの利点は幾つかあるが、その一つは、その事について慣れ親しむようになるということだ。いつも考え続けているので、そのテーマについてのことならば何時でも思い出したり検討したりする事ができる。

しかし、思い出すといっても同じ事を録音のように繰り返すだけでは意味がない。そのテーマについて意識的にいろいろな角度から検討する必要がある。意識的というのが大切で、意図的に記憶や資料へアプローチする必要がある。

意識的なアプローチのうちで最も有効なのはそのテーマを他の人に説明するにはどうすれば良いかと考えることだ。説明する内容の取捨選択やプレゼンテーションの構成を考えていく過程で突然に原著者の意図が分かることがある。

文書を読んでも、もうひとつ理解できたような気がしないときは、著作者の意図や企みが見えていないのだ。著述の構成がどうしてそうなっているのか、自分ならどう記述するだろうかを考えながら読みといていくうちに、著者のその文章を表した考え方が何となく見えてくる。

知識を構成する個々の要素は、他の要素との関連性の中で意味を持つ上に、要素の数が半端ではない。簡単に理解するコツなんてないし、写真のように頭の中に写し取ってしまうことは不可能だ。したがって攻略するためには何らかの戦略が必要なのだ。

これは、当たり前のことだが意外に意識していないことだ。普通は何となく本を読んで何となく分かったような気になっていることが多い。しかし、分からない、あるいは、覚えきれないと感じるときは、意図的な戦略が重要になる。

その意図的な戦略とは、「なぜそうなるのか」「その要素とあの要素にはなぜ関連があるのか」などと、「なぜ」という疑問を水先案内にしてその知識の要素間の関連や整合性を探索することだ。そして、これが最も効果的に行われるのは、その知識を他の人に伝えるには自分ならどうするかと考える場合だ。

新しい知識は、本質的に複雑な構造を内包していることが多い。そのような知識を扱うときは、慣れるまでどっぷりと浸かる覚悟がいる。
[PR]
by tnomura9 | 2015-03-23 05:19 | 考えるということ | Comments(0)

分からないとき

本を読んでも分からないときは、どうするのか。先ず、なぜ分からないのかをはっきりさせる必要がある。また、どうしたら分かったと感じることができるのかを知っていなければならない。

分かるということは、その知識を利用できるということだ。自分の知識のフレームワークのどこにその知識が位置づけられるのかを知っており、その知識を他の知識とどのように関連付けて運用することができるか知っているということだ。

分からないという感じは、ネガティブな感情を伴うので分からないことはスルーしやすいが、それが既存の知識のネットワークに組み込まれていないことを意味しているわけで、新しい知識を得るチャンスと捉えることもできる。

分からないと感じるときは、最初にその知識が既知の知識のどのカテゴリーに属しているかを考えるとよい。詳細は不明だが、少なくとも大まかにどのカテゴリーに属しているかを位置付ける事はできる。

また、その知識を自分がどのように利用したいのかを考える必要がある。どの知識でも、有意義なものは多量の内容を持っているから、そのすべてを一気に会得するのは不可能だ。差し当たり大量の詳細部分のどれを必要とするのかを意識する事は、その後の知識獲得のための戦略を立てるために必須の条件だ。

さらに、分からないことを理解するためには、その知識の背後にある大量の背景的な知識を知っておかなければならない。これは欠かすことのできない要件で、これをないがしろにしては先へ進めない。

そこで、文書を読んでいて分からないと感じた時は、質問票を作成するとよい。自分が何をわからないと感じているのか、どうして分からないと感じるのか、自分はこの文書からどのような情報を得たいと考えているのか、文書に書かれている情報のうちで自分に必要ないと考えられるのはどの部分か。なぜ必要ないと考えるのか、この文書を理解するための基礎知識はどのようなものか、その基礎知識はどこで得られるのか等々。

また、概念の境界が曖昧なために理解できないと感じることがある。その場合は、その概念に含まれるものと含まれないものに分けるのが効果的だ。このブロクでもT字型の線を引いて横線の上に概念のキーワードを書き、縦線の左に概念に属するもの、右に概念に属しないものを列挙する方法を紹介したことがある。

要するにわからないことは簡単には分かるようにはならないことを知っている事が大切だ。その上でその知識を既存の知識に有機的に組み入れていくための戦略を意識的に立てることが大切だ。
[PR]
by tnomura9 | 2015-03-16 13:14 | 考えるということ | Comments(0)

吉田松陰とソクラテス

今日NHKで『花燃ゆ』を見た。相変わらず舞台は松下村塾でドラマは進行している。毎回同じ舞台だ。吉田松陰は謹慎の身で外には出られないのだから当然といえば当然だ。しかし、松下村塾に集う人材の多士済々なのに驚かされる。間違いなく、江戸から明治に至る国難を救った人々の多くがここから育っていったのだろう。吉田松陰のどこにそのような力があったのだろう。

ドラマを見ていて、気がついたのは松陰が塾生の意見を頭から否定しないことだ。まず相手の言い分をよく聞いてその良いところを見つけようとする。あるいはその依って来るところの源泉を知ろうと努めているような気がする。その言葉を聞いているうちに、ソクラテスのやり方を思い出した。

プラトンの記述したソクラテスの対話をみていてまず不審に思ったのは、ソクラテスが自分の考えを全く述べていないところだ。対話の相手の意見をもとに、その利点や矛盾点を引き出していくのだが、その話題についてのソクラテス自身の考えは全く述べられない。

ソクラテスの相手は彼の質問に答えているうちに、自分の主張の矛盾点を暴かれて進退きわまってしまう。随分とソクラテスを恨んだことだろう。ソクラテスが殺される原因の一つだったのではないかと思ってしまう。しかし、ソクラテスはだからと言って相手に勝ち誇ったりはしていない。単に、意見の背後にあるもっと深い何かを自分で問い始めるのを見守ろうとしているだけだ。答えはソクラテスではなく対話の相手が探し出すべきものなのだ。

ソクラテスの自分の意見を言わないという態度は、それゆえに多様な人々に影響を与えることができる。異なる知識や経験をもつどの人々に対しても、ソクラテスはそれに対応し、その人たちの思考活動を刺激することができたのだ。当時の若者のソクラテス人気は自分が覚醒したことに対する喜びと感動によるものではなかったのだろうか。ソクラテスが解答を用意しなかったために、多様な環境や能力の人々の思考力を刺激することができた。

最近、有機農業の話を聞く機会があった。ある有機農業の農家の田圃では水を常に張っている。一般の農業では稲がある程度生育すると、田圃から水を引く作業が必要だそうだ。そうしないと、稲の株が増えすぎて生育障害が起きて収量や米の粒が小さくなる。しかし、その作業の間にセジロウンカが飛来すると壊滅的な影響を受けてしまう。セジロウンカが稲の根元から樹液を吸引するので稲が枯れてしまうのだ。

しかし、この有機農業の稲はセジロウンカが大量に飛来する場合にも影響を受けにくい。セジロウンカが稲の樹液を吸おうとして水面に近づくと、水面下に生息しているカエルや、ヤゴがこれを食べてしまうからだそうだ。有機農業の田圃の水は単なる水たまりではなく、様々な生物が生息する生態系だからだ。

害虫がいれば農薬で駆除する。雑草が増えれば抜いて捨てて化学肥料を施すというような在来農法ではこのような生態系を田圃の水中に育てることはできない。論理性や効率を尊重するあまり、多様性を失ってしまったのだ。このため、セジロウンカの大量飛来というような危機に対応できなくなってしまっているそうだ。

吉田松陰やソクラテスの人材の育て方は若者の多様性を阻害せず、むしろ多様性を保ったまま彼らに内在する可能性を引き出すように作用したような気がする。この人材の多様性こそが時代の危機を救ったのだろう。

スマホなどの興隆と凋落の変化の速さを見ると、現代の技術革新のスピードの影響で、部分的な最適化による生産力の向上では事がうまく働かない次元に至ったのではないかと思える。今こそ多様な人材からなる生態系の育成のあり方を模索する必要がある。
[PR]
by tnomura9 | 2015-03-15 23:51 | 考えるということ | Comments(0)

System.Random (13) 線形合同法

System.Random 解読シリーズ

擬似乱数列をコンピュータで発生させる時、よく使われるのが線形合同法である。簡単に言うと、現在の値の次にくる乱数を計算で発生させる方法だ。現在の値の次の値を、現在の値を関数の引数にすることによって次にくる値を計算する。これを次々と行っていけば乱数の数列を作ることができる。現在の値を次の値を計算するための引数にするので、最初の値(seed) が同じならば、同じ乱数の数列を発生させることができる。

線形合同法の関数は次のような簡単な関数だ。

Xn + 1 = (A * Xn + B) mod M

計算の過程で seed と同じ値が生成されれば、それからの数列はそれまでの数列が繰り返されることになるから、線形合同法の出力は周期的になる。周期の長さや出現する値の分布を調節するためには次のようなルールがある。

1. BとMが互いに素である。
2. A-1が、Mの持つ全ての素因数で割りきれる。
3. Mが4の倍数である場合は、A-1も4の倍数である。

理論だけを調べてもわかりにくいので ghci で実験してみた。

Prelude> let next x a b m = (x * a + b) `mod` m
Prelude> next 8 3 5 13
3
Prelude> next 3 3 5 13
1
Prelude> next 1 3 5 13
8

A = 3, B = 5, M = 13 で最初の値 (seed) を8にしたら、3回繰り返すと8に戻った。したがってこの数列は 8, 3, 1 を繰り返すはずだ。同じ操作を繰り返すのは面倒なのでプログラムしてみた。

Prelude> let nexts x a b m = x : nexts (next x a b m) a b m
Prelude> take 10 $ nexts 8 3 5 13
[8,3,1,8,3,1,8,3,1,8]

A, B, M の値を工夫すると周期をMと同じにして、0〜 M-1 の数を全て出現させることができる。

A = 13, B = 5, M = 24 の場合を実験してみた。

Prelude> take 30 $ nexts 0 13 5 24
[0,5,22,3,20,1,18,23,16,21,14,19,12,17,10,15,8,13,6,11,4,9,2,7,0,5,22,3,20,1]

わかりにくいので整列させてみた。

Prelude> Data.List.sort $ take 24 $ nexts 0 13 5 24
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]

System.Random の stdNext のソースは次のようになる。線形合同法そのままではなく、2つの乱数列を作り、その差を利用しているようだが理論的なことはわからなかった。次の乱数の発生のためには現在の乱数ではなくランダムジェネレータである整数のペアが使われている。

stdNext :: StdGen -> (Int, StdGen)
-- Returns values in the range stdRange
stdNext (StdGen s1 s2) = (fromIntegral z', StdGen s1'' s2'')
        where        z'   = if z < 1 then z + 2147483562 else z
                z    = s1'' - s2''

                k    = s1 `quot` 53668
                s1'  = 40014 * (s1 - k * 53668) - k * 12211
                s1'' = if s1' < 0 then s1' + 2147483563 else s1'
    
                k'   = s2 `quot` 52774
                s2'  = 40692 * (s2 - k' * 52774) - k' * 3791
                s2'' = if s2' < 0 then s2' + 2147483399 else s2'
[PR]
by tnomura9 | 2015-03-01 18:40 | Haskell | Comments(0)

グラフと排中律

素朴集合論の集合の世界は個体と集合という2種類の対象とそれらをつなぐ所属関係という射によって作られるグラフである。しかし、このグラフの対象に排中律を適用するとパラドックスが発生してしまう。なぜだろうか。それは素朴集合の対象は単なる対象ではなく、所属関係という射によって構造を与えられているからだ。

相互に関連のない対象の集まりに対しては、これを命題の述語を充足するものとそうでないものによって分けることに矛盾は発生しない。これらのどの対象も述語を充足するかしないかを判断できるし、充足するものの集まりや、充足しないものの集まりを考えることができる。

素朴集合論の集合の問題点は、ラッセルの集合のような、集合の世界のどの対象をとっても、述語を充足するか、充足しないかを判断できるにもかかわらず、「自分自身を要素として含まない集合の集合」をつくることができないことがあるということだ。

これは素朴集合論の世界の対象には所属関係という射が存在することによって、その対象に構造が発生しているからだ。対象のあいだの相互作用のない直感的な集合とは性質が異なっているのである。つまり、「集合とはものの集まりというものである」という集合を対象の一つと考える定義が、集合にそのネットワークの一員であることを強制しているのだ。この対象間の所属関係という構造のために、「自分自身を要素として含まない」集合は容易に見つけることができるにもかかわらず、それを集めて「集合」にすることができないのだ。

注意しないといけないのは、「自分自身を要素として含まない集合」の「集まり」は考えることができる。しかし、その「集まり」が「集合」と呼ばれるためには、それは対象として素朴集合のネットワークに組み込まれていなければならない。この集まりを「集合」として素朴集合のネットワークに組み込もうとした時にラッセルの述語ではパラドックスを発生してしまうのだ。

これは、ラッセルの集合が無限集合であるから発生するわけではない。図書館のパラドックスは素朴集合の構造についての非常に適切なモデルであるが、これを熟考すれば、ラッセルの集合を作ることができないのは無限のせいではないことがわかる。

よく知られた推論のように「自分自身に言及しない書籍の目録」はパラドックスをひきおこすため作ることができないが、図書館に所蔵されていない目録なら「図書館の書籍のうちで自分自身に言及しない書籍の目録」を容易に作ることができる。図書館に所蔵されていなければ、その目録は図書館の書籍のネットワークに含まれないからだ。

たしかに、素朴集合論の対象と所属関係の射からなるグラフには、排中律を無制限に適用することはできない。集合論を数学の基礎に据えようとする立場からはこれは大変なことで、集合論をまったくすてさるのではなく、素朴な所属関係のネットワークに制限を加えることで、集合のネットワークと排中律のすり合わせを図ったのが公理的集合論ではなかったのだろうか。

しかし、単なる印象だが、それは数学の危機を救うためにあまりに急いで行われた応急処置でしかなかったような気がする。つまり、なぜ素朴集合論のグラフと排中律の対立が起こったのか、また、どのような制限を素朴集合論のグラフに与えれば問題が解決されるのかが明らかにされていないのだ。公理的集合論はすでに確立した学問だし、そこを詮索してもあまり新しいことは発見できないかもしれないが、すくなくとも教育的な見地からは、学習者を煙に巻くような「素朴集合論には矛盾がある、だから、抽象的で理解できない公理的集合論が必要なのだ」というような表現をしなくてもよいようになってほしい。
[PR]
by tnomura9 | 2015-03-01 07:57 | 考えるということ | Comments(0)