Haskellの型について

こんばんは、south37です。今日はHaskellの型についてお話ししたいと思います。

強い静的型付け言語、Haskell

Haskellは「強い静的型付け言語」と呼ばれています。静的型付け言語とは、文字通り静的な型を付ける必要のある言語で、CやC++,Javaのような変数や関数の定義時に型を明記する必要のある言語がこれに相当します。

それでは、「強い」とは何でしょうか?

Wikipedia先生によればこれは「型検査によって型安全性が保証される」、よりざっくり言えば暗黙の型変換なんかが許容されないことです。(この辺は人によって定義が分かれるらしいです) C言語なんかは、弱い型付けに分類されます。大きさを指定して宣言した配列の境界チェックは行われないですし、ポインタの指す先に保証はありません。つまり、「変数の値の型が分からない」といった状態がありうる訳で、そういった意味で「弱い」型付け言語と呼ばれます。

逆に、Haskellは強い型付け言語である為、そういった心配はありません。コンパイルを通ったならば、少なくとも型安全性は保証されている訳です。

Haskellにおける型

ここから、Haskellにおける型を見て行きたいと思います。まず、Haskellにおいては、様々な「値」や「関数」がみな型を持っています。

:t True      -- True :: Bool

factorial n = product [1..n]
:t factorial -- factorial :: Integer -> Integer

関数の型については前回もお話しましたね。Haskellにおいては、リストやタプルも個別の型になります。

:t [1, 2, 3] -- [1, 2, 3] :: Num t => [t]
:t ('a', 2)  -- ('a', 2) :: Num t => (Char, t)

リストは「単一の型のリスト」という型になるのに対して、タプルは「ある値とある値(とある値...)のタプル]という型になります。タプルにおいてはいろいろな型の変数をまとめる事が出来る為、その組み合わせごとに個別の型とする訳です。

ここまではいいですね。

型クラス

次に、型クラスというものについてお話したいと思います。「型クラス」というのはざっくり言うと「型に対して何らかの振る舞いを定義するインターフェイス」で、ある型クラスに属するという事実から、型の振る舞いを保証する事が出来ます。

例えば、ある値の集合をsortしたいとします。その時、値同士の大小を比較出来なければ、sortは原理上不可能ですよね?そういった時に、「Ord型クラス」に属すると分かれば、比較が出来る事が保証される為、sortを安全に行う事が出来る訳です。

こういった型クラスはHaskellにおいてはデフォルトでいくつも定義されていて、主なものとしては、「等しいか判定出来る事」を保証する「Eq型クラス」、先程も例に挙げた「大小判定出来る事」を保証する「Ord型クラス」、「文字列への変換が出来る事」を保証する「Show型クラス」などが存在します。

さて、これらの「型クラス」に属するという事は、具体的には何を意味するのでしょうか?Haskellにおいては、これは「ある特定の関数が実装されている事」を意味します。

例えば、「Eq型クラス」に属する型の値は、==関数と/=関数に対して振る舞いが定義されています。(/=は等号否定の意味で、他の言語だとよく!=とかで表されてるヤツです。)

'a' == 'a' -- True。'a'はChar型で、Char型はEq型クラスに所属。

つまり、ある型クラスに属している値であると分かれば、特定の関数を安心して使う事が出来る訳です。

型クラス、いい仕組みですね!!

手続き型言語オブジェクト指向とかとの比較

さて、ここまでお話しした型クラス、何かに似ていると思いませんか?僕だけかもしれませんが、「ある特定の振る舞いが定義されている事を保証する」という意味で、オブジェクト指向における「抽象クラス」を利用する方法に似ている気がしました。

つまり、オブジェクト指向の言語における、ある特定のメソッドが呼び出せる事を保証する為に抽象クラスを継承させるというアプローチが、Haskellにおける型クラスの仕組みに対応していると思う訳です。

これは僕の個人的な印象で、専門の人からすれば全然ちゃうわって感じかもしれません。ただ、やっぱりプログラミングにおいては「インターフェイスを上手く合わせる」事がむちゃくちゃ重要で、その為のアプローチとしては色んな手法がありえるんだなって再認識しました。

今日はこんな感じで終わりです!

すごいHaskellたのしく学ぼう!

すごいHaskellたのしく学ぼう!