メッセージキュー用のlibを作成しています。キューはDirect
またはTopic
のいずれかです。 Direct
キューには静的バインディングキーがあり、Topic
キューには動的バインディングキーを設定できます。タイプの1つのコンストラクタでしか機能しない関数
Direct
キューでのみ機能するpublish
を書いてみたいと思います。これは動作します:
{-# LANGUAGE DataKinds #-}
type Name = Text
type DirectKey = Text
type TopicKey = [Text]
data QueueType
= Direct DirectKey
| Topic TopicKey
data Queue (kind :: a -> QueueType)
= Queue Name QueueType
これは、2つの個別のコンストラクタ
directQueue :: Name -> DirectKey -> Queue 'Direct
topicQueue :: Name -> TopicKey -> Queue 'Topic
が必要です。しかし、私は公開書くために行くとき、私は
publish :: Queue 'Direct -> IO()
publish (Queue name (Direct key)) =
doSomething name key
publish _ =
error "should be impossible to get here"
不可能であるべきと一致する必要があり、余分なパターンがありますこのパターンマッチングを必要としないように、この問題をモデル化するより良い方法はありますか? Direct
キューは常にText
メタデータを持ち、Topic
キューは常に[Text]
メタデータを持つ必要があります。タイプと値の両方でこれを実施するより良い方法はありますか?
は、あなたの代わりに2つの異なるタイプ 'のnewtype DirectQueue = DQ Text'と' newtypeのTopicQueue = TQ [テキスト]のパラメータ化 'Queue'タイプを、'必要な理由はありますか? – chepner
@chepner - 彼らはお互いに共通点があります。私は問題を単純化するために余分な情報を取り出した。これをサンプルに戻してデモンストレーションします。 –
キューの 'Name'に、共通の情報があることを示すために追加しました。実際のアプリケーションでは、どのキューでも機能するいくつかの関数があり、キューにはキューの種類に加えて2つの別個のフィールドがあります。 –