現在、非常に恐ろしい関数unsafeCoerceを使用している状況があります。幸いなことに重要なことではありませんが、これがこの関数の安全な使用法であると思われるのか、それとも他の人が知っているこの特定の問題を解決する別の方法があるのでしょうか。
私が持っているコードは次のようなものです:
data Token b = Token !Integer
identical :: Token a -> Token b -> Bool
identical (Token a) (Token b) = a == b
data F a = forall b. F (Token b) (a -> b)
retrieve :: Token b -> F a -> Maybe (a -> b)
retrieve t (F t' f) = if identical t t' then Just (unsafeCoerce f) else Nothing
注意すべき2つの追加事項は、これらのトークンは、整数の供給が一意であることを確認するために使用するモナド内で使用されることです(つまり、同じトークンを2回作成しない)。また、STモナドと同じように、forallの定量化されたシャドウ型変数を使用して、(モジュールで公開するメソッドのみが使用されていると仮定して)トークンを返す方法がないことを確認します(実際には、 F)型エラーではなくモナドから。また、トークンコンストラクターも公開していません。
私が見る限り、これはunsafeCoerceの安全な使用法であると思います。私が強制している値は、実際には私が強制しているタイプとまったく同じであるというかなり高い確信を持って言えるでしょう。 、しかし私は間違っているかもしれません。また、Data.Typeableを使用してみましたが、これはうまく機能しますが、現時点では、Typeableの制約を回避するためにこれを試みています。特に、gcastは多くの点で同様のことを行うようであり、区別するためにトークンが必要です。同じタイプの異なるF。
ヘルプ/アドバイスをありがとうございました。