haskell - {-# #-} 在 Haskell 中的用途

标签 haskell

我正在经历Haskell code看看我如何编写类似的流融合函数,我注意到一个有趣的语法结构,{-# ... #-},我没有遇到过;所以我想知道它是什么以及如何了解它是如何工作的:

-- | /O(n)/ Drop elements that do not satisfy the predicate
filter :: Vector v a => (a -> Bool) -> v a -> v a
{-# INLINE filter #-}
filter f = unstream . inplace (MStream.filter f) . stream

更具体地说,特定行有什么作用?
{-# INLINE filter #-}

最佳答案

GHC 有一个“pragma”系统,它允许您为 GHC 指定额外的语言信息。特别是,它们看起来像

{-# <NAME> <ARGS...> #-}

您将看到的最常见的是语言扩展编译指示,它必须位于文件的顶部并影响对文件其余部分有效的语言扩展。
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Example where

通常应该是忽略编译指示不会影响程序的含义。这对于像 INLINE 这样的 pragma 来说是正确的。因为它们只是向编译器提示该函数的主体应该在调用它的任何地方内联,以便开辟新的优化机会。 Haskell 语义为我们保证了这种内联转换何时不会改变程序的含义,因此编译器关于是否内联的选择对程序的含义没有影响(只要它不违反程序的含义)这些保证的假设)。
LANGUAGE pragma 有点不同,因为它们准确地指定了文件其余部分所用的语言。例如,我们通常假设基本语言是 Haskell98Haskell2010LANGUAGE pragmas 添加扩展名,以便前面举例说明的带有标题的文件的语言是
Haskell2010 + RankNTypes + FlexibleInstances + ScopedTypeVariables

但除了向编译器暗示正在编写哪种语言之外,这些 pragma 没有其他意义。

整套允许的编译指示取决于所使用的编译器。 GHC's pragmas are listed here (请注意,此链接适用于 7.6.3 版,而评论中的链接适用于 7.0.3 版)。使用除 LANGUAGE 以外的编译指示可能是粗略的和特定于平台的,因此请仔细了解它们的用途和含义。

例如,关于图书馆作者是否应该使用 INLINE 存在很大争议。因为它往往表明对 GHC 自己的内联启发式方法缺乏信心,因此我们应该花更多的精力来收紧这些启发式方法,而不是用手册 INLINE 乱扔代码s。话虽如此,INLINEINLINABLE如果使用得当,可以对紧密的内部循环产生深远的影响。

关于haskell - {-# #-} 在 Haskell 中的用途,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22773699/

相关文章:

Haskell:类型类与传递函数

haskell - 模式匹配,匹配多个字符

algorithm - 简单的行转置密码

haskell - Fundeps 和 GADT : When is type checking decidable?

haskell - 是否有带有显式子类型的 ADT 名称?

haskell - 数字参数化向量的 Monad 实例?

macos - OS X上的Haskell音频输出?

haskell - 为什么GHC说这两种类型不一样?我怎样才能让它们相同?

list - 递归函数的惰性模式

haskell - 操作真的与自由单子(monad)同构吗?