時々、私が書きたいコードが、少なくとも 1 つの言語拡張がないと正しくないことがあります。これは、研究論文でアイデアを実装しようとするときに特に当てはまります。研究論文では、実際に必要な拡張機能が明確に示されずに、論文が書かれた時点で利用可能な GHC の洗練された超拡張バージョンが使用される傾向があります。
その結果、.hs ファイルの先頭に次のような内容が記述されることがよくあります。
{-# LANGUAGE TypeFamilies
, MultiParamTypeClasses
, FunctionalDependencies
, FlexibleContexts
, FlexibleInstances
, UndecidableInstances
, OverlappingInstances #-}
それは気にしませんが、GHC の偉大な神をなだめるために盲目的に犠牲を払っているように感じることがよくあります。言語拡張 X がないと特定のコードが有効ではないというエラーが表示されるので、X のプラグマを追加します。次に、Y を有効にするように要求されるので、Y のプラグマを追加します。これが完了するまでに、よく理解できない言語拡張を 3 つまたは 4 つ有効にしてしまい、どれが「安全」なのかまったくわかりません。
「安全」の意味を説明します。
UndecidableInstances
コンパイラが終了しない可能性はありますが、コードがコンパイルされる限り予期しない副作用は発生しないため、これは安全だと理解しています。一方、は
OverlappingInstances
明らかに安全ではありません。ランタイム エラーを引き起こすコードを誤って記述してしまう可能性が非常に高いからです。
「安全」とみなされる GHC 拡張機能と「安全でない」とみなされる GHC 拡張機能のリストはありますか?
ベストアンサー1
おそらく、何を見るのが一番良いでしょうセーフハスケル許可:
安全な言語
セーフ ランゲージ ( を通じて有効化
-XSafe
) は、次の 2 つの異なる方法で制限を行います。
- 特定の GHC LANGUAGE 拡張は完全に禁止されています。
- 特定の GHC LANGUAGE 拡張機能は機能が制限されています。
各カテゴリに分類されるフラグと拡張機能の詳細は次のとおりです。
- 完全に禁止:
GeneralizedNewtypeDeriving
、TemplateHaskell
- 制限された機能:
OverlappingInstances
、、、ForeignFunctionInterface
RULES
Data.Typeable
- 制限されている機能については以下を参照してください
- 重要ではありません: 残りのすべてのフラグ。
制限および無効化された GHC Haskell 機能
Safe 言語方言では、次の Haskell 言語機能が制限されます。
ForeignFunctionInterface
: これはほぼ安全ですが、IO 以外の型の関数をインポートする外部インポート宣言は許可されません。すべての FFI インポートは IO モナド内に存在する必要があります。RULES
: 信頼できるコードの動作を予期しない方法で変更し、意味の一貫性を侵害する可能性があるため、機能が制限されています。具体的には、コンパイルされたRULES
モジュールで定義されたものはすべて削除されます。インポートされた信頼できるモジュールで定義されたものは引き続き有効であり、通常どおり実行されます。M
-XSafe
RULES
M
OverlappingInstances
: この拡張機能は、悪意のあるコードが (より具体的なインスタンス定義を含めることによって) 型インスタンスを再定義して、信頼できないモジュールをインポートするコードの動作を変更する可能性があるため、意味の一貫性を侵害するために使用される可能性があります。拡張機能は、M
でコンパイルされたモジュールに対して無効にはなりません-XSafe
が、制限されます。 はM
重複するインスタンス宣言を定義できますが、 でのみ使用できます。をインポートするM
モジュールで、型クラス関数を使用する呼び出しサイトで、使用するインスタンス (つまり、重複) の選択肢があり、最も具体的な選択肢が からのものである場合 (またはその他の安全にコンパイルされたモジュール)、コンパイルは失敗します。モジュールが安全であると見なされるか、信頼できると見なされるか、またはそのどちらでもないかどうかは関係ありません。N
M
M
N
Data.Typeable
: のインスタンスの派生は許可しますData.Typeable
が、手動で作成されたインスタンスは許可しません。派生インスタンスは GHC によって機械生成され、完全に安全であるはずですが、手動で作成されたインスタンスは型について嘘をつき、型間の安全でない強制変換を許可する可能性があります。これは、SYB の元の設計の精神に基づいています。Safe 言語方言では、次の Haskell 言語機能を完全に無効にします。
GeneralizedNewtypeDeriving
: 信頼できないコードが保護されたデータ型をデータ型の作成者が意図していない方法で操作できるようにすることで、コンストラクタのアクセス制御に違反する可能性があります。つまり、データ構造の不変条件を破壊するために使用できます。TemplateHaskell
: コンパイル時にも副作用を引き起こし、抽象データ型にアクセスするために使用できるため、特に危険です。TH を使用すると、モジュール境界を破ることは非常に簡単です。
FunctionalDependencies
との相互作用も安全ではない可能性があると読んだことを思い出します。UndecidableInstances
無制限のコンテキストスタックの深さを許可するだけでなく、UndecidableInstances
いわゆる補償条件(セクション 7.6.3.2) ですが、現時点ではこれに関する引用を見つけることができません。
編集 2015-10-27: GHC が型ロールのサポートを獲得して以来、GeneralizedNewtypeDeriving
安全ではなくなりました。(他に何が変わったのかはわかりません。)