第7章 GHCの言語機能

目次

7.1. 言語オプション
7.2. 非ボックス化型とプリミティブ演算
7.2.1. 非ボックス化型
7.2.2. 非ボックス化タプル
7.3. 構文的拡張
7.3.1. Unicode構文
7.3.2. 魔法の井桁(magic hash)
7.3.3. 負数リテラル
7.3.4. 小数風整数リテラル
7.3.5. 階層的モジュール
7.3.6. パターンガード
7.3.7. ビューパターン
7.3.8. パターンシノニム
7.3.9. n+kパターン
7.3.10. 伝統的なレコード構文
7.3.11. 再帰的do記法
7.3.11.1. 再帰的束縛グループ
7.3.11.2. mdo記法
7.3.12. 並行リスト内包表記
7.3.13. 一般化(SQL風)リスト内包表記
7.3.14. Monad内包表記
7.3.15. 再束縛可能な構文とPreludeの暗黙インポート
7.3.16. 後置演算子
7.3.17. タプルのセクション
7.3.18. ラムダcase
7.3.19. 空のcase選択肢
7.3.20. 多選択肢のif式
7.3.21. レコードフィールドの曖昧性除去
7.3.22. レコード同名利用
7.3.23. レコードワイルドカード
7.3.24. 局所結合性宣言
7.3.25. パッケージ修飾されたインポート
7.3.26. safeインポート
7.3.27. インポート/エクスポートの際の名前空間の明示
7.3.28. 盗まれた構文の概略
7.4. データ型と型シノニムへの拡張
7.4.1. 構築子のないデータ型
7.4.2. データ型文脈
7.4.3. 中置型構築子、中置クラス、中置型変数
7.4.4. 型演算子
7.4.5. 型シノニムの制限緩和
7.4.6. 存在量化されたデータ構築子
7.4.6.1. どこが存在的か?
7.4.6.2. 存在型と型クラス
7.4.6.3. レコード構築子
7.4.6.4. 制約
7.4.7. 構築子のシグネチャを明示してデータ型を宣言する
7.4.8. 一般化代数データ型(GADT)
7.5. 「deriving」機構への拡張
7.5.1. deriving節について推論される文脈
7.5.2. 独立deriving宣言
7.5.3. より広範なクラスについてのderiving節(TypeableDataなど)
7.5.4. Typeableインスタンスを自動的に導出する
7.5.5. newtypeについての自動導出インスタンスの一般化
7.5.5.1. deriving節の一般化
7.5.5.2. より精密な規定
7.6. クラスおよびインスタンス宣言
7.6.1. クラス宣言
7.6.1.1. 多引数の型クラス
7.6.1.2. クラス宣言のスーパークラス
7.6.1.3. クラスメソッドの型
7.6.1.4. デフォルトメソッドシグネチャ
7.6.2. 関数従属
7.6.2.1. 関数従属に関する諸規則
7.6.2.2. 関数従属の背景
7.6.3. インスタンス宣言
7.6.3.1. インスタンスの解決
7.6.3.2. インスタンス頭部に関する規則の緩和
7.6.3.3. インスタンス文脈に関する規則の緩和
7.6.3.4. 決定不能インスタンス
7.6.3.5. 重複インスタンス
7.6.3.6. インスタンス宣言中の型シグネチャ
7.6.4. 文字列リテラルの多重定義
7.6.5. リストの多重定義
7.6.5.1. IsListクラス
7.6.5.2. 構文の再束縛
7.6.5.3. デフォルト化
7.6.5.4. 未来についての考察
7.7. 型の族
7.7.1. データ族
7.7.1.1. データ族宣言
7.7.1.2. データインスタンス宣言
7.7.1.3. データインスタンスの重複
7.7.2. シノニム族
7.7.2.1. 型族宣言
7.7.2.2. 型インスタンス宣言
7.7.2.3. 閉型族
7.7.2.4. 型族の例
7.7.2.5. 型族の等式間の互換性と分離性
7.7.2.6. 型シノニムインスタンスの決定可能性
7.7.3. 関連データ族と関連型族
7.7.3.1. 関連インスタンス
7.7.3.2. 関連型シノニムのデフォルト
7.7.3.3. クラスパラメタのスコープ規則
7.7.3.4. インスタンス文脈と、関連型および関連データインスタンス
7.7.4. インポートとエクスポート
7.7.4.1. 例
7.7.4.2. インスタンス
7.7.5. 型族とインスタンス宣言
7.8. 種多相
7.8.1. 種多相の概観
7.8.2. 概観
7.8.3. 多相種再帰と完全な種シグネチャ
7.8.4. 閉型族における種推論
7.8.5. クラスインスタンス宣言における種推論
7.9. データ型の昇格
7.9.1. 動機
7.9.2. 概観
7.9.3. 型と構築子の区別
7.9.4. 昇格したリスト型とタプル型
7.9.5. 存在的なデータ構築子の昇格
7.9.6. 型演算子の昇格
7.10. 型水準リテラル
7.10.1. 型水準リテラルに対応する実行時の値
7.10.2. 型水準自然数を使った計算
7.11. 等式制約
7.11.1. Coercible制約
7.12. Constraintという種
7.13. 型システムへのその他の拡張
7.13.1. 明示的な全称量化(forall)
7.13.2. 型シグネチャの文脈
7.13.3. 曖昧な型、および曖昧性検査
7.13.4. 暗黙パラメタ
7.13.4.1. 暗黙パラメタ型制約
7.13.4.2. 暗黙パラメタの束縛
7.13.4.3. 暗黙パラメタと多相再帰
7.13.4.4. 暗黙パラメタと単相性
7.13.5. 明示的に種付けされた量化
7.13.6. 任意ランク多相
7.13.6.1. 例
7.13.6.2. 型推論
7.13.6.3. 暗黙の量化
7.13.7. 非叙述的多相
7.13.8. 字句的スコープを持つ型変数
7.13.8.1. 概観
7.13.8.2. 宣言型シグネチャ
7.13.8.3. 式型シグネチャ
7.13.8.4. パターン型シグネチャ
7.13.8.5. クラス宣言とインスタンス宣言
7.13.9. 束縛および一般化
7.13.9.1. 恐怖の単相性限定を無効にする
7.13.9.2. 相互再帰的な束縛に対する型付けの一般化
7.13.9.3. letにおける一般化
7.14. 型付き穴
7.15. 型エラーを実行時まで遅らせる
7.15.1. 型エラーの遅延を有効にする
7.15.2. GHCiで型エラーを遅らせる
7.16. Template Haskell
7.16.1. 構文
7.16.2. Template Haskellを使う
7.16.3. Template Haskellの実例
7.16.4. Template Haskellをプロファイルと併用する
7.16.5. Template Haskellの準クォート
7.17. アロー記法
7.17.1. コマンドのdo記法
7.17.2. 条件コマンド
7.17.3. 制御構造を自分で定義する
7.17.4. プリミティブな構成要素
7.17.5. 論文との差異
7.17.6. 可搬性
7.18. びっくりパターン
7.18.1. びっくりパターンについての非形式的な説明
7.18.2. 構文と意味論
7.19. アサーション
7.20. プラグマ
7.20.1. LANGUAGEプラグマ
7.20.2. OPTIONS_GHCプラグマ
7.20.3. INCLUDEプラグマ
7.20.4. WARNINGおよびDEPRECATEDプラグマ
7.20.5. MINIMALプラグマ
7.20.6. INLINEおよびNOINLINEプラグマ
7.20.6.1. INLINEプラグマ
7.20.6.2. INLINABLEプラグマ
7.20.6.3. NOINLINEプラグマ
7.20.6.4. CONLIKE修飾子
7.20.6.5. 段階制御
7.20.7. LINEプラグマ
7.20.8. RULESプラグマ
7.20.9. SPECIALIZEプラグマ
7.20.9.1. SPECIALIZE INLINE
7.20.9.2. インポートした関数のSPECIALIZE
7.20.9.3. 旧式のSPECIALIZE構文
7.20.10. SPECIALIZE instanceプラグマ
7.20.11. UNPACKプラグマ
7.20.12. NOUNPACKプラグマ
7.20.13. SOURCEプラグマ
7.21. 書き換え規則
7.21.1. 構文
7.21.2. 意味論
7.21.3. 書き換え規則と、INLINE/NOINLINEおよびCONLIKEプラグマとの間の相互作用
7.21.4. リストの融合変換
7.21.5. 特殊化
7.21.6. 書き換え規則の中で何が起こるか制御する
7.21.7. COREプラグマ
7.22. 特殊な組込み関数
7.23. 総称クラス
7.24. 総称プログラミング
7.24.1. 表現を導出する
7.24.2. 総称関数を書く
7.24.3. 総称的デフォルト
7.24.4. さらなる情報
7.25. 役割
7.25.1. 名目、表現、幽霊
7.25.2. 役割推論
7.25.3. 役割注釈
7.26. Concurrent HaskellおよびParallel Haskell
7.26.1. Concurrent Haskell
7.26.2. Software Transactional Memory
7.26.3. Parallel Haskell
7.26.4. 純粋なコードに並列計算用の注釈を加える
7.26.5. Data Parallel Haskell
7.27. Safe Haskell
7.27.1. Safe Haskellの用途
7.27.1.1. 厳格な型安全性(良いスタイル)
7.27.1.2. セキュアなシステムを構築する(制約付きIOモナド)
7.27.2. safe language
7.27.3. safeインポート
7.27.4. 信頼とSafe Haskellのモード
7.27.4.1. 信頼検査(-fpackage-trustが無効の場合)
7.27.4.2. 信頼検査(-fpackage-trustが有効の場合)
7.27.4.3. 例
7.27.4.4. Trustworthyの要件
7.27.4.5. パッケージへの信頼
7.27.5. Safe Haskellの推論
7.27.6. Safe Haskellのフラグまとめ
7.27.7. 安全なコンパイル

既知のHaskell処理系はどれもそうだが、GHCもいくつかの言語拡張を実装している。これらは、コマンド行フラグやプラグマを使って有効/無効を切り替えられる。デフォルトでGHCが理解するのは、対応しているうちで最新のHaskellに、多少の拡張を加えたものである。

グラスゴー拡張の中には、Haskellを実装するのに使われている基礎となる機能に触れるようにするものがある。よって、可搬性のないコードを原始的な水準で書くつもりがあるなら、生の部分を操作することができる。効率を追求するとき、Haskellの高水準な機能の実装コストのせいで行き詰まる必要はない。常にそれらの機能の「下」でコードを書けるからである。極端な場合、速度が重要な部分は全てCで書き、それをあとでHaskellと合わせる、ということもできる。

最低水準での作業に没頭する(例えば、至るところでMutableByteArray#を使ったり)前に、必要な機能に「Haskellらしい被覆」を被せるライブラリがないか確かめた方が良いだろう。ライブラリ説明書(訳注: 未訳。web上の最新版)にはGHC付属のライブラリが全て説明されている。

7.1. 言語オプション

言語オプションのフラグは、言語のどの変種が許されるか制御するものである。

言語オプションは二つの方法で制御できる。

  • 全ての言語オプションは"-X..."というコマンド行フラグ(例えば-XTemplateHaskell)によって有効に、"-XNo..."というフラグ(例えば-XNoTemplateHaskell)によって無効にできる。

  • Cabalが認識する言語オプションなら、LANGUAGEプラグマを使って有効にすることもできる。{-# LANGUAGE TemplateHaskell #-}のように。(7.20.1. LANGUAGEプラグマを見よ)

-fglasgow-extsフラグは、以下の拡張を有効にするのと同じである。-XForeignFunctionInterface-XUnliftedFFITypes-XImplicitParams-XScopedTypeVariables-XUnboxedTuples-XTypeSynonymInstances-XStandaloneDeriving-XDeriveDataTypeable-XDeriveFunctor-XDeriveFoldable-XDeriveTraversable-XDeriveGeneric-XFlexibleContexts-XFlexibleInstances-XConstrainedClassMethods-XMultiParamTypeClasses-XFunctionalDependencies-XMagicHash-XExistentialQuantification-XUnicodeSyntax-XPostfixOperators-XPatternGuards-XLiberalTypeSynonyms-XRankNTypes-XTypeOperators-XExplicitNamespaces-XRecursiveDo-XParallelListComp-XEmptyDataDecls-XKindSignatures-XGeneralizedNewtypeDeriving-fglasgow-extsの効果は、これらのオプションを有効にすることだけである。我々はこの多目的フラグをやめて、機能を個別に有効にする方向に移行しようとしている。