37

時折、私が書きたいと思っているコードが、少なくとも 1 つの言語拡張がなければ合法ではないことがあります。これは、研究論文でアイデアを実装しようとするときに特に当てはまります。研究論文では、どの拡張機能が実際に必要であるかを明確にせずに、論文が書かれた時点で利用可能だった、気の利いた超拡張バージョンの GHC を使用する傾向があります。

その結果、.hs ファイルの先頭に次のようなものが表示されることがよくあります。

{-# LANGUAGE TypeFamilies
           , MultiParamTypeClasses
           , FunctionalDependencies
           , FlexibleContexts
           , FlexibleInstances
           , UndecidableInstances
           , OverlappingInstances #-}

私はそれを気にしませんが、GHC の偉大な神をなだめるために盲目的な犠牲を払っているように感じることがよくあります。特定のコードは言語拡張 X なしでは無効であると不平を言うので、X のプラグマを追加します。次に、Y を有効にするように要求するので、Y のプラグマを追加します。これが完了するまでに、私は私がよく理解していない 3 つまたは 4 つの言語拡張機能を有効にすると、どれが「安全」なのかわかりません。

「安全」の意味を説明するには:

  • UndecidableInstancesコンパイラが終了しない可能性がありますが、コードがコンパイルされる限り、予期しない副作用が発生しないため、安全であることは理解しています。

  • 一方、OverlappingInstancesは明らかに安全ではありません。実行時エラーを発生させるコードを誤って記述しやすくなるためです。

だから私の質問は:

「安全」と見なされ、「安全でない」GHCextensions のリストはありますか?

4

1 に答える 1

39

SafeHaskellで何が許可されているかを確認するのがおそらく最善です。

安全な言葉

Safe Language ( で有効化-XSafe) は、次の 2 つの方法で物事を制限します。

  1. 特定の GHC LANGUAGE 拡張機能は完全に許可されていません。
  2. 特定の GHC LANGUAGE 拡張機能は、機能が制限されています。

以下は、各カテゴリに分類されるフラグと拡張機能です。

  • 完全に許可されていません: GeneralizedNewtypeDerivingTemplateHaskell
  • 制限された機能: OverlappingInstancesForeignFunctionInterfaceRULESData.Typeable
    • 以下の制限付き機能を参照してください
  • 重要ではありません: 残りのすべてのフラグ。

GHC Haskell 機能の制限および無効化

Safe 言語方言では、次の Haskell 言語機能を制限します。

  • ForeignFunctionInterface: これはほとんど安全ですが、非 IO 型の関数をインポートする外部インポート宣言は許可されません。すべての FFI インポートは IO モナドに存在する必要があります。
  • RULES: 信頼できるコードの動作を予期しない方法で変更できるため、セマンティックの一貫性に違反して機能が制限されます。具体的には、でコンパイルRULESされたモジュールで定義されたものはすべて削除されます。インポートがまだ有効であり、通常どおり起動する信頼できるモジュールで定義されています。M-XSafeRULESM
  • OverlappingInstances: 悪意のあるコードは、信頼されていないモジュールをインポートするコードの動作を変更する方法で (より具体的なインスタンス定義を含めることによって) 型インスタンスを再定義する可能性があるため、この拡張機能を使用してセマンティックの一貫性を侵害することができます。Mでコンパイルされ-XSafeたが制限されているモジュールでは、拡張機能は無効になりません。重複するインスタンス宣言をM定義できますが、それらは でのみ使用できますMNをインポートするモジュールでM、型クラス関数を使用する呼び出しサイトで、使用するインスタンス (つまり、オーバーラップ) の選択があり、最も具体的な選択がM(または他の Safe コンパイル済みモジュール) からのものである場合、コンパイルは不合格。モジュールNが安全と見なされるか、信頼できると見なされるか、どちらでもないと見なされるかは関係ありません。
  • Data.Typeable: のインスタンスのData.Typeable派生は許可されていますが、手作りのインスタンスは許可されていません。派生インスタンスは GHC によって生成されたマシンであり、完全に安全である必要がありますが、手作りのインスタンスはその型について嘘をつき、型間で安全でない強制を許す可能性があります。これは、SYBのオリジナルデザインの精神にあります。

Safe 言語方言では、次の Haskell 言語機能を完全に無効にします。

  • GeneralizedNewtypeDeriving: データ型の作成者が意図しない方法で、信頼されていないコードが保護されたデータ型を操作できるようにすることで、コンストラクターのアクセス制御に違反するために使用される可能性があります。つまり、データ構造の不変条件を破るために使用できます。
  • TemplateHaskell: コンパイル時でも副作用を引き起こす可能性があり、抽象データ型へのアクセスに使用できるため、特に危険です。TH を使用すると、モジュールの境界を簡単に破ることができます。

無制限のコンテキスト スタックの深さを許可することを超えて、いわゆるカバレッジ条件FunctionalDependencies(セクション 7.6.3.2) も解除されるため、 andの相互作用も安全ではない可能性があることを読んだことを思い出しますが、現時点ではこれに関する引用が見つかりません。 .UndecidableInstancesUndecidableInstances

EDIT 2015-10-27: GHC が型ロールのサポートを獲得して以来、GeneralizedNewtypeDerivingもはや安全ではありません。(他に何が変わったのかはわかりません。)

于 2012-05-31T10:22:49.200 に答える