mod q
を表すタイプdata Zq q = Zq Int
を含むライブラリがあります。安全のために、私はこのタイプの操作((+)
、(*)
など)を公開したいと思いますが、ではなくコンストラクタをエクスポートして、最初にそのような型を宣言して安全を迂回する人を回避します。安全性と拡張性を得る
しかし、ライブラリのユーザーは、ライブラリ作成者が予測できないこのタイプのインスタンスを宣言する必要があります。名前にちょうど少数の可能なインスタンス:DeepSeq
、Storable
、Unbox
、...
私はそのことを知っている唯一の方法は、第三者がそのような事例を行うことができますコンストラクタをエクスポートすることです。 (あるいは、スマートなコンストラクタとデストラクタを定義してエクスポートすることもできますが、これはデータコンストラクタをエクスポートするだけのことにはなりません)。
安全性を確保する方法はありますか?
1つのオプションは、名前に 'Unsafe'を含む別のモジュールからのみコンストラクタをエクスポートすることです。このようにして、ユーザーが適切なことを行うのは簡単ですが、必要に応じて、コンストラクターには引き続きアクセスできます。 – kosmikus
'Zq'ではパターンマッチングを許可したいが、構築は許可したくないようだ。 'PatternSynonyms'では、これは簡単です:'パターンView_Zq a < - Zq a'。 GHC> = 7.10でさらに進んで明示的な双方向パターンシノニムを書くことができます。これは、式の文脈で 'Int'が正しいサイズであるかどうかをチェックし、そうでなければエラーを投げます(あるいは' mod q'をそれがあなたに合っていれば整数)。古いバージョンでは、オリジナルと同じ*ビュー*タイプでも同じことを達成できますが、ビュータイプを元のものに変換することはできません。 'view :: Zq q-> View_Zq q'。 – user2407038
..しかし、あなたはすでにこのアイデアを持っているようです(第3段落) - なぜこれはデータコンストラクタをエクスポートするよりも優れていませんか?あなたは、非抽象化関数 'Zq q - > Int'と' IsNat q => Int - > Maybe(Z q) 'で述べたすべてのクラスを実装することができます。 – user2407038