Haskellで特異メソッド

(この記事はHaskell Advent Calendar 2012の記事です。)

HaskellでReal World Problemを解いていると、オブジェクト指向でいうところのオブジェクトを作りたくなることはよくあります。Haskellでは、だいたい代数データ型とレコード構文がその役割を担ってきました。Haskellはレコードを自由に扱えなかったのですが、Lensの登場により、レコードは苦手科目から超得意科目へと変わりつつあります。

それでも、データ型は何だか融通が聞かない奴、という感じがします。開発途上で新しいレコードを追加したくなることはよくありますが、そもそもデータ型を定義しなおすのは面倒ですし、データ型を定義しなおしたら、その型の値を作っているところをすべて書き直さねばなりません。 あまつさえリアルワールドでは、全ての値についてレコードの値が得られないこともあるし、レコードを持っている値と持っていない値をいっしょのリストに入れて扱いたいときもあったりします(動物学をやっていて、技術の進歩により新たに動物の角の長さが測定できるようになったとします。でも、きりんは背が高すぎて未測定だったり、兎には角がなかったりしますよね。)

hasのアプローチのように、HasHornというインスタンスメソッドを持つ型クラスを作る、という手もあります。でも、これだと動物ごとに違う型を作ることになり、動物をぜんぶ同じリストに入れることはできません。

型クラスが、型に対するオープンなインターフェイスであるように、メソッドを持つ値に対するオープンなインターフェイスは作れないものでしょうか?具体的には、Duck Typingや、特異メソッドを、Haskellの型システムを活かす形で、実現できないでしょうか?