パターンマッチ
前のページで、type
キーワードを用いたカスタム型の書き方について学びました。
主要な例としてチャットルームの User
型を定義しました:
type User
= Regular String Int
| Visitor String
Regular
ユーザーは名前と年齢を持っているのに対し、Visitor
ユーザーは名前だけを持っているのでした。
このようにカスタム型の作り方は分かりましたが、実際にはどのように使えば良いのでしょうか?
case
各 User
から表示する名前を返す関数 toName
を定義したいとします。
case
式を使う必要があるでしょう:
toName : User -> String
toName user =
case user of
Regular name age ->
name
Visitor name ->
name
-- toName (Regular "Thomas" 44) == "Thomas"
-- toName (Visitor "kate95") == "kate95"
case
式は渡されたバリアントごとに処理を分岐できます。なのでRegular
のトーマスが来ようがVisitor
のケイトが来ようが名前の表示の仕方は常にわかっています。
そしてもし、toName (Visitar "kate95")
や toName Anonymous
のような不正な引数を与えた場合には、コンパイラがそのことについてすぐに教えてくれるでしょう。
これによって多くの単純なミスが数秒で修正でき、プログラマーが自分でミスを見つけないといけないような言語と比べて全体の開発時間を大いに削減できるのです。
ワイルドカード
上で定義したtoName
関数はうまく動きますが、age
の値を実装内で使っていませんよね?使っていない関連データには名前を付ける代わりに「ワイルドカード」を使うのが普通です。
toName : User -> String
toName user =
case user of
Regular name _ ->
name
Visitor name ->
name
_
はそこになんらかの値があることを示しつつも、実際にはその値が特に使われていないことを表現しています。