20

GHC のマニュアル、Section Safe Languageから:

モジュール境界制御— 安全な言語を使用してコンパイルされた Haskell コードは、他のモジュールのエクスポート リストを通じて公開されているシンボルにのみアクセスすることが保証されます。これの重要な部分は、安全にコンパイルされたコードは、インポートできないデータ コンストラクターを使用してデータ値を調べたり作成したりできないことです。モジュール M がそのエクスポート リストを慎重に使用していくつかの不変条件を確立する場合、M をインポートする安全な言語を使用してコンパイルされたコードは、それらの不変条件を尊重することが保証されます。このため、このプロパティに違反するために使用される可能性があるため、安全な言語ではTemplate Haskellが無効になっています。GeneralizedNewtypeDeriving

を使用してモジュールの不変条件をどのように破ることができGeneralizedNewtypeDerivingますか?

4

1 に答える 1

29

Luquiは、この件に関する私のブログ投稿にリンクしました。基本的に、GeneralizedNewtypeDerivingGHC で実装されているように、 はある種の同型 (すなわち、 によって暗示される操作的に無関係な同型newtype) がライプニッツの等式を意味すると仮定しています。これは、Haskell 98 ではある程度当てはまりましたが、Haskell と拡張機能ではまったく当てはまりません。

つまり、newtype は関数のペアを提供します。

a -> b
b -> a

コアでは何もしませんが、結論としては問題ありません

forall f. f a -> f b

f型関数または GADT である可能性があるためです。これが必要な平等の形式ですGeneralizedNewtypeDeriving

Haskell 98 でさえ、モジュール境界を壊します。あなたは次のようなものを持つことができます

class FromIntMap a where
  fromIntMap :: Map Int b -> Map a b

instance FromIntMap Int where
  fromIntMap = id

newtype WrapInt = WrapInt Int deriving FromIntMap

instance Ord WrapInt where
  WrapInt a <= WrapInt b = b <= a

悪いことをするもの...

私のブログ投稿では、unsafeCoerce他の拡張機能 (すべて安全) を使用していくつかの方法を実装する方法を示しGeneralizedNewtypeDeriving. ており、なぜこれが現在なのかをよりよく理解しており、「システム FC」スタイルの拡張機能 (type familes、type familes GeneralizedNewtypeDerivingunsafeCoerceGADT)。シル、それは安全ではなく、使用する場合は注意して使用する必要があります. 私の理解では、Lennart Augustsson (ユーザー augustss) が hbc で非常に異なる方法で実装し、この実装は安全でした。安全な実装はより制限され、より複雑になります。

更新: GHC の十分な新しいバージョン (すべての問題は 7.8.1 の時点で解消されているはずです)では、新しいロール システムGeneralizedNewtypeDerivingにより安全です。

于 2013-06-16T21:03:24.190 に答える