今日、とあるツイートでプログラミングにおけるよくある問題が顕現していた。プログラミングしてそうなサークル探したら、ゲーム公開してて、ソースコード公開されてたから見た。4奇妙な行コメントには目を瞑るとして、このコードは要約すれば以下のような処理を実現していることが窺える。ゲームプログラミングでは、現在のシーンによって処理を切り替える必要がある。メニュー画面ならメニューの処理を、戦闘画面なら戦闘を、マップならマップの表示をそれぞれ行う。現在のシーンの種類は変数によって与えられる。その変数の値によって、対応する処理を選ぶ。してみると単純だが、caseによる単純な分岐では扱いにくい。新しいシーンを作るたびに場合分けを書き換えなければならないし、何よりそれは「処理」と「処理を表す値」の一覧表を作るという面白みのない処理だからだ。一つの(そして、よく用いられる)解決法はオブジェクト指向プログラミングである。各シーンをオブジェクトとして扱うことにより、問題となっている分岐を扱う必要がなくなる。新たに、操作の集まりによって定義される「インターフェイス」という構造を導入する。以下の疑似コードでは、Sceneとして扱う型は、drawという処理が使えることを示している。draw()インターフェイスによって定められた操作を実装するのが「クラス」である。Menu、Map、Battleという3つのクラスを定義し、それぞれ異なるdrawの実装を持っている。...これらの処理を実際に使うには「インスタンス」を用いる。Menu()これはMenuの実体を持つインスタンスを生成し、sに代入する操作を表す。ここで得られたインスタンスsはSceneの型を持つ(サブタイピングがあれば、Menuの型を持ってもよいが、Sceneであることがここでは重要である)。s.draw()はSceneが保証しているdrawの処理を実行する。Map()で生成した場合はMapのdrawになる。ここで注目すべきは、コードや型は一緒でも、実際に行われる処理は動的に決まるという点だ。今までは、シーンを表す値を見て処理を自分で選択しなければならなかったが、その必要がなくなっているのがわかる。したがってシーンの種類が増えても、drawを呼ぶ部分を修正する必要はない。このようなことを可能にしているのか?そのからくりはインスタンスに宿っている。インスタンスは言語によって様々な実装方法があるが、大きく分けて「クラス(処理)のインデックス」か「処理そのもの」のどちらかがインスタンスの内部に隠れている。前者の場合、s.draw()は、sの中身のインデックスを元に、対応するクラスのdrawを取り出して実行する。Battle()で作ればBattleを表す値が入っている(文字列でも数値でも、一意に対応させられれば何でもよい)。今までの方法と実は全く同じだが、自動化されていると言える。後者はより簡単で、インスタンスにはインターフェイスが保証する処理の実装がすべて入っている。s.draw()は、sの中に入っているdrawの処理を取り出しているに過ぎない。C++などの静的型付きの言語は前者を、Pythonなどの動的型付きの言語は後者を取る傾向がある。静的型付きの言語であるHaskellではどちらの方法でも実現できるが、あまり使われていない。いずれにせよ、特にゲームプログラミングにおいて、動的に処理を選択したい場合は少なくない。オブジェクト指向がその便利な解決法であることは間違いなく、実際にゲームプログラミングで使われている言語のほとんどはオブジェクト指向をサポートしている。人類は、酒と共に発展してきたと言っても過言ではない。穀物や...2016-10-10割とすぐに始められるextensibleチュートリアル(レコード編)ごきげんよう諸君。今回はextensibleについて説明しよう。joinedHaskellはてなブログをはじめよう!fumiexcelさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。