Haskell pragmas:OPTIONS_GHC vs LANGUAGE

AJF*_*mar 7 haskell language-extension

我发现自己在我的阴谋项目中使用了这种实用工具来迫使GHC使用特定选项进行构建:

{-# OPTIONS_GHC -XFlexibleInstances -XRankNTypes ... #-}
Run Code Online (Sandbox Code Playgroud)

但当我看到其他人使用扩展时,他们总是以这种方式声明它:

{-# LANGUAGE FlexibleInstances, RankNTypes, ... #-}
Run Code Online (Sandbox Code Playgroud)

但是,当我在使用后一种方法的GHCi中加载文件时,GHC总是抱怨我正在使用unrecognised pragma并迅速失败.

为什么GHC不接受这个LANGUAGEpragma,哪两个是更好的做法?


注意:我的GHC版本是最新的:7.8.3,但是当发生这种情况时是7.6.*.

zud*_*dov 12

使用LANGUAGEpragma更好.它不是给出任意选项的列表,而是仅针对语言扩展.如GHC文档中所述,它还可以在实现之间移植;LANGUAGE

...允许以便携方式启用语言扩展.所有Haskell编译器都希望LANGUAGE使用相同的语法支持pragma,当然并非所有编译器都支持所有扩展.LANGUAGE编译应当用来代替OPTIONS_GHC,如果可能的话.[强调补充]

GHC6.6(§7.10.4)开始,LANGUAGE通过GHC 7.10.1(§7.22.1),当前(撰写本文时)发布时,同样的语言出现在文档中.

指定语言扩展的第三种方法是在cabal文件中声明它们.

我还发现使用LANGUAGEpragma为单个文件声明已使用的扩展是很常见的,但是使用OPTIONS_GHC(在单个文件的级别上)通常用作解决方法(例如,禁用某些警告).人们更喜欢在项目范围内(使用cabal)声明GHC选项而不是单个文件,而由于某些原因,语言扩展通常用于每个文件.

以下是一些猜测为什么LANGUAGEpragma可能无法识别的猜测:

  • 你有一个古老的GHC版本(<6.6)
  • 您不会将其声明为文件头编译指示.文件头编译指示必须位于module文件中的关键字之前.换句话说,它应该位于文件的最顶层(尽管它可能在其他文件头编译指示之前)

  • "LANGUAGE"扩展通常是每个文件的原因是为了确保读取该文件的任何人都知道正在使用哪些扩展.很高兴知道"GeneralizedNewtypeDeriving","OverlappingInstances","IncoherentInstances","MonoLocalBinds","ScopedTypeVariables","DataKinds"和/或"PolyKinds"是否正在发挥作用,这些(至少)可能不完全其他来源显而易见. (6认同)