※この記事は「型クラスで見るPureSciript」の連載記事です。
ショーの開幕
この記事を読みに来てくださった皆様、ありがとうございます。「型クラスで見るPureSciript」第1回Show型クラスの幕開けです。
最初はウォーミングアップ程度の話題ですが、しばしの間、お付き合いください。
型クラスとは
まずはじめに型クラスとは何であるかを簡単に説明しましょう。
型クラスというのはPureScriptを特徴付ける機能の1つであり、Javaや.NETにおけるInterfaceのような役割を担う機能です。型クラスの定義は次のように記述します。
class Show a where
show :: a -> String
上記のa
という変数は型変数と呼ばれており、データ型名に置きかわります。このコードは次のように理解します。
「型クラスShow
には、データ型a
からString
への関数show
が定義されていること。」
これをオブジェクト指向言語のように書き換えると、次のようになります。
interface Show {
public String show();
}
この2つを見比べると、インターフェースの役割を担う機能であることを直感的に理解できると思います。ここでは、型引数a
はオブジェクト指向言語のthis
に相当するものと思っておけば大丈夫です。
型クラスの実装
型クラスは、オブジェクト指向言語のインターフェースに相当することから分かるように、型クラスを定義しただけでは、何の役にも立ちません。型クラスを定義したら、型クラスのインスタンスを実装して初めて、役に立つコードになります。
試しに、先ほどのShow型クラスをBooleanデータ型に実装したコードを見てみましょう。
instance showBoolean :: Show Boolean where
show true = "true"
show false = "false"
型クラスを実装するには、インスタンス名という名前をつけなければなりません。ここでは"showBoolean"というのがインスタンス名になります。インスタンス名は何でも良いのですが、慣例的に「型クラス名+データ型名」を使うことが多いようです。
インスタンス名に引き続き、ダブルコロン::
、型クラス名Show
、型引数Boolean
を書きます。そして、where
ブロックに型クラスの関数定義を記述します。
今の例では、型クラスには1つの関数しか定義されていませんでしたが、もちろん、複数の関数が定義されている型クラスもありますし、定数値が定義された型クラスもあります。また、データ型に対して印をつける目的から、定義されているメンバが0個の型クラスもあります。
型クラスの継承関係
オブジェクト指向言語のインターフェースと同じように、型クラスにも継承関係を構築することが可能です。型クラスを継承するには次のように書きます。
class Eq a <= Ord a where
compare :: a -> a -> Ordering
このように書くことで、型クラスOrd
は型クラスEq
をスーパークラスに持つことになります。すると、データ型a
に対して型クラスOrd
を実装するには、先に型クラスEq
を実装しておくことが必要になります。
また、型クラスは多重継承をすることも可能なので、次ような書き方もできます。
class (Applicative m, Bind m) <= Monad m
Show型クラス
それでは最も基本的な型クラス(?)であるShow型クラスについて見てみましょう。(やっとここまで来ました)
Show型クラスはオブジェクト指向言語で言う所のObject.toString()
に相当する型クラスです。Show型クラスを実装しなくても実用的なプロフラムを作ることは可能なのですが、PSCIでテストするときなど、Show型クラスを実装しておかないと、値の検証をするのに不便なことが多いです。テストコードのためにもデータ型を定義したらShow型クラスだけは実装しておくことをオススメします。
まずはShow型クラスを実装するためのデータ型を作りましょう。
data Person = Person String String
ここで左側のPerson
がデータ型名です。右側のPerson
は値構築子(値コンストラクタ)と呼ばれています。値構築子Person
は2つのString型引数を取ります。(若干正確な表現ではないですが、初めはこういう理解で十分でしょう。)
データ型Person
はfirstNameとfamilyNameの2つの値を保持するデータ型です。そこで、データ型Person
にShow型クラスを実装してみましょう。
instance showPerson :: Show Person where
show (Person a b) = a <> " " <> b
これをPSCIで実行して見ると次のようになります。
> him = Person "John" "Smith"
> show him
"John Smith"
ちなみに、PSCIでは実行した式に対してshow関数を適用して得られる文字列を表示するので、単にhim
と書いても値を表示できます。(形式の若干の違いはありますが)
> him
John Smith
今夜のショーはここで閉幕
さて、今回は簡単に型クラスの紹介をしました。次回からは、PureScriptの代数的側面にフォーカスを当てて書いていこうと思います。それでは、また次回。
演習問題
電話番号を表すデータ型を次のように定義します。
data Phone = Phone Int Int Int
このデータ型Phone
に対して、Show型クラスを実装してください。
参考文献
Show型クラスについては下記のページを参考にしました。