分かっていない人が書いてる、いきなりHaskellモナド入門

Haskellを勉強するにあたって重要な概念があります。それがモナドです。モナドとは、計算を合成して計算するときの作戦です。モナドを使うと、プログラムの組み合わせを手で書くことを自動的に行ってくれるのでプログラムが楽になります。たとえばMaybeというモナド、Maybe作戦があります。Maybeは答えを返すかもしれないし返さないかもしれない計算の作戦名です。Maybe作戦は、
AとBの2つの計算の合成した計算をしようというときに、AかBの答えがなければ答えはなしで、答えがでるときはAの答えをBの計算で使って答えがでる。という作戦です。
ここで、日常的な物事での具体的な例をあげます。伝言ゲームをします。まず入力データとして、問題がAさんにこっそり教えられます。Aさんはそのまま正しい答えを渡すか、間違えた答えをBさんに教えます。BさんはAさんの答えを紙に書きます。Aさんはギャグ好きで、うその笑える答えをBさんに教えようとする可能性があります。それをBさんは知っています。問題を出す先生はまじめな人なので、ギャグ的な答えが出てきたらそれはうそ。まじめにやっても無駄だということを知っています。ここで、使えるのがMaybe作戦です。Bさんはギャグになってたら、まじめに伝えません。疲れるだけですから、適当に聞いて適当に答えます。そのほうが楽です。メンドクサイから、「あ」でいいやと「あ」と答えます。で、さっさと終わらせて駄弁ってたほうがいいと。50人いたら、間違いと判断したら、でかい声で「あ」と叫んだら、最後の人が適当な答えを書いて終了でも、どうせ間違ってるんだからいいだろ。って作戦、それがMaybe作戦です。騎馬戦にもおそらくそういった作戦があるように、モナドもいろいろなモナドがあります。」


Haskellでは入出力周りに沢山モナドが使われています。
プログラマにとってモナドは関数プログラムの構造化に有用なツールです。主な性質は3つあります。

  • モジュラリティ
  • 柔軟性
  • 分離性

モジュラリティってのは作戦立てる人と実行する人を分けることができるってこと。インターフェイスとプログラムを分けて書けるということだわな。
柔軟性ってのは作戦だけまとめてかけるからその分柔軟だと。普通のプログラムは作戦とプログラムがごちゃごちゃまざってるからな。デザインパターンとかもクラス名に反映されて、複数のクラスに分けて書くくらいのことしかできんだろうが、モナドは、作戦をきっちり定義できるということよ。わかったか。
分離性ってのは関数プログラミングと命令スタイル、つまりC言語とかの言語でかくプログラミングスタイルを分離できると言うこと。
ようは作戦のインターフェイスとプログラムが分かれるってだけのことだ。

で、使い方にはいる。MaybeのHaskellでの定義はこう。

data Maybe a = Nothing | Just a

コレの意味は、data の後ろに書いてあるMaybeが型を作る奴で、Nothing , Justってのはデータを作る奴。
だから、Maybeっていう型を作る奴はaといわれると、何もデータ返さないか、aってデータを返すよって作戦だよということを言ってることになるのよ。わかった?

data OreOreSagi a = Nothing | Just a

とかくと、オレオレ詐欺作戦は電話で話すとお金が儲かるかも知んないし、儲かんないかもしれないってことだ。

HaskellではJustはこんな風に使います。

country = Just "China"

これで、国には中国があるよってことになる。

country = Just "China"
        | Just "Japan"
        | Just "Koria"

なんてつかう。C言語でいうenumです。C言語知らない人ごめんな。ていうか間違えてる可能性大。要は例が足りなくてわからないっていうこと。

同じようにMaybeを使って作戦が作れる。何々作戦は何々作戦を使って何々作戦もくみあわせちゃうぞということが出来ると言うわけだ。書き方はこんなかんじ。

lookupAge :: DB -> String -> Maybe Int

まずコレを理解するには多相型をしらないといけません。多相型っていうのは例えばデータのリストをHaskellでは

[1,2,3] ['a','b','c'] [[1,2],[2,3],[3,4]]のように書きますが、

これはデータの型だけ見ると、
[数字,数字,数字] [文字,文字,文字] [数字2つのリスト,数字2つのリスト,数字2つのリスト]となっており、これは
[a,a,a]と書けます。さらに長さが3ではなくていくつでもいいものをあつかいたいと。そんなときに多相型関数をいかのように定義できます。

length                  :: [a] -> Integer
length []               =  0
length (x:xs)           =  1 + length xs

この定義は、これだけで十分説明になります。この等式をこんなふうに読むことができます。「空リストの長さは 0 、最初の要素がxで残りが xsであるようなリストの長さは 1 にxsの長さを加えたものである。」(ここでは命名の習慣がつかわれていることに注意してください。 xsはxの複数形で、読むときもそのように読みます。)
[1,2,3]というリストは、 1:2:3:[]というリストの簡略表記です。

[1,2,3]=1:[2,3]=1:2:[3]=1:2:3:[]

です。


ああ、カリー化関数もしらないといけない。その前にタプルを説明しないといけない。ぐほー。ってことで、多相型の関数にモナドなんかつかわんでくれよーと言いたい。行きなり難しすぎですよ。