2016-10-30 22 views
2

mod qを表すタイプdata Zq q = Zq Intを含むライブラリがあります。安全のために、私はこのタイプの操作((+)(*)など)を公開したいと思いますが、ではなくコンストラクタをエクスポートして、最初にそのような型を宣言して安全を迂回する人を回避します。安全性と拡張性を得る

しかし、ライブラリのユーザーは、ライブラリ作成者が予測できないこのタイプのインスタンスを宣言する必要があります。名前にちょうど少数の可能なインスタンス:DeepSeqStorableUnbox、...

私はそのことを知っている唯一の方法は、第三者がそのような事例を行うことができますコンストラクタをエクスポートすることです。 (あるいは、スマートなコンストラクタとデストラクタを定義してエクスポートすることもできますが、これはデータコンストラクタをエクスポートするだけのことにはなりません)。

安全性を確保する方法はありますか?

+3

1つのオプションは、名前に 'Unsafe'を含む別のモジュールからのみコンストラクタをエクスポートすることです。このようにして、ユーザーが適切なことを行うのは簡単ですが、必要に応じて、コンストラクターには引き続きアクセスできます。 – kosmikus

+0

'Zq'ではパターンマッチングを許可したいが、構築は許可したくないようだ。 'PatternSynonyms'では、これは簡単です:'パターンView_Zq a < - Zq a'。 GHC> = 7.10でさらに進んで明示的な双方向パターンシノニムを書くことができます。これは、式の文脈で 'Int'が正しいサイズであるかどうかをチェックし、そうでなければエラーを投げます(あるいは' mod q'をそれがあなたに合っていれば整数)。古いバージョンでは、オリジナルと同じ*ビュー*タイプでも同じことを達成できますが、ビュータイプを元のものに変換することはできません。 'view :: Zq q-> View_Zq q'。 – user2407038

+0

..しかし、あなたはすでにこのアイデアを持っているようです(第3段落) - なぜこれはデータコンストラクタをエクスポートするよりも優れていませんか?あなたは、非抽象化関数 'Zq q - > Int'と' IsNat q => Int - > Maybe(Z q) 'で述べたすべてのクラスを実装することができます。 – user2407038

答えて

5

ほとんどの整形式インスタンスでは、安全でない生コンストラクタは必要ありません。 Unboxなどは少し低レベルですが、他のインスタンスは一般に、最終アプリケーションに使用するのと同じ高レベルAPIで定義する必要があります。

インスタンスがわからない場合は⇒実際にはコンストラクタを非表示にすることはできません。クリティカルに近い金属のインスタンスを自分で定義するだけであれば大丈夫です。

しかし、ライブラリがコンストラクタをまったくエクスポートしないと、私はしばしば迷惑をかけることがあります。すべてのインスタンスや他のすべてがの場合でもは高度APIを使用してのみ定義することができますが、は実際には見逃すことのできない多くの理由で安全でない低レベルのアクセスを許可する意味があります。 何が起きているのか ...
したがって、Pythonの“we're all consenting adults here”の哲学と同様に、私はkosmikusの提案を支持したいと思います。すべての重要な型のコンストラクタをエクスポートします。これらを直接使用すると安全でないことが明らかになります。余分なUnsafeモジュールがこれを実現する良い方法です。コンストラクタに技術的にわかりやすい名前を付けるだけでも十分です。そしてもちろん、これらの輸出について何が正確に安全でないかを文書化する。