私はいくつかの呼び出しが追加の情報を返すためのフラグを取るWebサービスへのバインディングに取り組んでいます。例えば、IDを介してアーティストを取得することは、アーティストのレコーディングを返すために 'レコーディング'フラグを取ることができ、IDによるリリースを取得することは、そのリリースのトラックのすべてのレコーディングを取得するためにレコーディングフラグを取ることもできる。ただし、アーティストを取得する際には、そのアーティストによるすべてのリリースを取得できますが、実際に特定のリリースを取得した場合は無効です。どのようにフラグを持つ型システムを、時には共有され、時には排他的な関数に使うことができますか?
だから、Haskellのにそれをエンコードするために、次は有効なプログラムでなければなりません:
getArtistById 5678 [ WithRecordings ]
getReleaseById 37837 [ WithRecordings ]
し、次は、無効なプログラムであっても、およびビルドに失敗する必要があります。
getReleaseById 739 [ WithReleases ]
私はいくつかの解決策を考えましたが、どちらを取るべきかわかりません。最初に考えたのは、タイプクラスArtistFlag
とReleaseFlag
を使用することでしたが、これはいくつかの理由で意味をなさないものです。まず、ArtistFlag f => [f]
は、脆弱な同じフラグのリストを意味します。しかし、型クラスは将来的に余分なフラグを追加することを意味します。これはあまり意味がありません。有限個のフラグがあります。
私の次のオプションは、各エンドポイントフラッグのための独立したデータ宣言した:
data ArtistFlag = ArtistWithRecordings | ArtistWithReleases
data ReleaseFlag = ReleaseWithRecordings
これはで動作するようにちょっと不格好です - プログラマのためのAPIを簡素化するために、理想的*WithRecordings
は常に同じ名前を持つ必要があります。
最後に、これは私が知識が不足しているために調査していない唯一のオプションですが、これはHListによって解決できる可能性があります。 getArtistByIdは異種のアーティストフラグセットを取るべきです。私はまだHListでこれを表現する方法はまだ分かっていません。
達人は私が実装してるAPIの:)
実際の部品がhttp://musicbrainz.org/doc/XML_Web_Service/Version_2#Subqueriesである言っているかのタイピングを聞くのが大好きだ - 完全にあなたの質問を取るなど、recordings
フラグに気づく
"無効なプログラム"の例で 'getReleaseById 739 [WithReleases]'行しか持たないと思います。 – ehird
@ええ、ええ、それをキャッチするために感謝します。 – ocharles
[Type Directed Name Resolution](http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution)は、この問題に対する(まだ実装されていない)解決策です。 –