2014-03-31 78 views
5

我正在通過Haskell code來了解如何編寫類似的流融合函數,並且我注意到了一個有趣的語法結構{ - #...# - },沒有遇到;所以我想知道它是什麼以及我怎樣才能知道它是如何工作的:Haskell中的{ - ## - }的用途

-- | /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 #-} 
+3

文檔:http://www.haskell.org/ghc/docs/7.0.3/html/users_guide/pragmas.html特別指出,試圖讓編譯器對函數進行內聯優化。 –

回答

11

GHC有一個「編譯指示」系統,允許您指定GHC的額外語言信息。特別是,它們看起來像

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

,你會看到最常見的是語言擴展編譯指示其必須在文件的頂部,影響語言擴展在該文件的其餘部分的影響。

{-# LANGUAGE RankNTypes #-} 
{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE ScopedTypeVariables #-} 

module Example where 

通常情況下,應該是忽略編譯指示不會影響程序的含義。對於像INLINE這樣的編譯指示來說,這大致如此,因爲它們僅僅是提示編譯器,爲了打開新的優化機會,該函數的主體應該被內聯到任何地方。 Haskell語義爲我們保證了這種內聯轉換何時不會改變程序的含義,因此編譯器選擇是否內聯對程序的意義沒有影響(只要它不違反這些保證的假設)。

LANGUAGE pragmas有點不同,因爲它們指定文件的其餘部分準確寫入什麼語言。例如,我們通常假設的基本語言是Haskell98Haskell2010LANGUAGE編譯指示添加擴展,使得早期的領導列舉的文件的語言是

Haskell2010 + RankNTypes + FlexibleInstances + ScopedTypeVariables 

但除此之外暗示來的語言被寫入編譯這些雜注沒有更多的意義。


完整的允許編譯指示集取決於使用的編譯器。 GHC's pragmas are listed here(請注意,此鏈接適用於版本7.6.3,而註釋中的鏈接適用於7.0.3)。使用除LANGUAGE以外的編譯指示可能會粗略且針對平臺,因此請認真學習它們的用法和含義。

例如,有大約庫作者是否應該使用INLINE因爲它往往表明,在GHC自己的內聯啓發式缺乏信心,因此,我們應該花更多的精力收緊這些了,而不是亂拋垃圾代碼,一個大辯論手冊INLINE s。但是,這說,如果明智地使用,INLINEINLINABLE可以對嚴密的內循環產生深遠的影響。

+0

D'oh,儘管我已經在谷歌索引真正舊版本的文檔中搜索過多次,但您會認爲我會知道檢查我的GHC版本以查看最新版本。 –

+1

另請參見[Haskell 2010報告:編譯器Pragma](http://www.haskell.org/onlinereport/haskell2010/haskellch12.html#x19-18800012)('LANGUAGE' pragmas不是[98報告]的一部分( http://www.haskell.org/onlinereport/pragmas.html),但是'INLINE'和'NOINLINE'是)。 – Zeta

6

這是一個編譯。它基本上是語言標準本身不能表達的東西,但仍然在說與編譯器相關的東西。

其中一些編譯指示本質上是可選的,例如,提高表現,因此評論般的外觀。在你的例子中,INLINE意味着編譯器應該儘量不要將鏈接添加到有問題的函數中,而是實際上將它「硬編碼」到它調用的任何地方。這原則上不會改變程序的語義,但會對性能和內存使用產生相當大的影響(特別是如果與額外的流融合等技術相結合)。