型と値 Part1

いい加減に『ふつうのHaskellプログラミング』読み終わってるところまでのまとめをしておきます
昨日から書き貯めてたのですが、あまりにも長く書いてしまったので2つに区切ります

【静的型チェックと型推論
Haskellではコンパイル時に静的型チェックをします
この際に他言語では当たり前の『型宣言』はHaskellでは必ずしも必要ではありません
言語処理系が型を推測して補ってくれるのです
これを『型推論』といいます
コンパイル時に型推論の結果矛盾無く全ての式が型付け出来ればエラーにはなりません
が、型を明示しておいた方がいいと思います
型推論では式に対して最も広い範囲で適用出来そうな型をまず適用します
仮に型推論の結果エラーにならなかったとしても自分が目指す式と違っていたら意味がありません
なので、型を明示して後から式を見ても分かるように、プログラムの目的を明確にするために
型は書くべきだと思います
勿論型推論は使い方によってはとても便利に使えると思います
ここの箇所はどうして型推論が成立するのか型推論の謎についてすごく考えました

【基本的な型】

【型】      【意味】       【値の例】
Int                 整数値        -1, 0, 1, 777
 Char            文字                  'a' , 'A' , '\n'
String         文字列        "abc" , "String"
Bool                真偽値         True , False
[○○のリスト]      ○○のリスト     [1, 2, 3]

※Intは最低30bit幅の符号付き整数値を意味します
 詳しくはとても分かりやすい説明を参照して下さい

【関数の型】
関数の型は引数の型と返り値の方の組み合わせで関数の型を表現します

  String   ->   [ String ]

これは第一引数がStringで返り値の値が[ String ]である関数の型を表します
つまりaという引数でリスト[ a ]を返す関数の型という事を表してます
lines関数は文字列を行のリストに分割する関数でした
なので、この String   ->   [ String ] という式はlines関数を示します
またwords関数も同じ型です

   [String]  ->  String 

この式は先程の式の逆なのでunlines関数を示します

【型変数】

  [ a ]   ->  Int

この[a]のリストの型を考えて行きたいと思います
このaは型変数( type variable )といいどんな型と置き換えてもよいのです
この型変数を含む型の事を多相型( polymorphic type )と呼びます
ではなんで型変数が必要になるのかlength関数を例にとって上の式を解いて行きたいと思います
その前にまずおさらい

length関数  リストの長さ(要素の数)を返す関数 どんな値のリストでもlength関数で調べられる
特に、文字列の長さを調べるのにも使える

以上の事からlength関数の型が多数存在するということが分かります
けど、これだけではよく分からないので実際に型を書き出してみると以下のようになります

[ Char ]  ->  Int
[ Int ]   ->  Int
[ Bool ]  ->  Int
    ・
   ・
   ・

これをまとめて共通部分を抜き出すと

[ Char or Int or Bool or ・・・]  -> Int

[a]のリストの要素が文字か整数値か真偽値か・・・そのリストの返り値が整数値で返ってくるのですが
length関数は要素の数で返すので[a]のリストにはいろいろな型が当てはまります
ただ、この場合よく分からなかったのが[ Bool ]です
[ Bool ] -> Int ではどういう返り値が返ってくるのか分かりませんでした
そこでもう一度[a]のリストについて考えてみます

[ Bool ]   ->  Int
[a]のリストに[Bool]を適用した結果Intで返ってくる
つまり、真偽値の要素を整数値で返す式

なのでこの型もlength関数を表す式なのです
ここはきちんと理解してたつもりだったけど復習してみたらまたつまずいたので
もう一度考える事になりました
簡単だと思ってたけど以外と難しい箇所でした

型と値 Part2に続く・・・