2013-07-07 63 views
21

Haskell 2010保證在編譯時連接字符串文字嗎?Haskell在編譯時連接字符串文字嗎?

如果我有

"This is a " ++ 
"very long String that " ++ 
"spans several lines" 

該編譯器把它當作

"This is a very long String that spans several lines" 

我想如果可能的話讓我的源線長少於80個字符,但我不希望引入運行時效率低下。

回答

16

使用一個間隙中的一個或多個空格字符反斜槓之間的序列:

"This is a \ 
\very long String that \ 
\spans several lines" 

零寬度當量\&,用於從數字字符分離數字逃逸有用:

"\123\&45" == "{45" 
"\12345" == "〹" 
19

Haskell 2010保證它與合併的字符串在指示上相當,但沒有關於應該如何編譯的說明。雖然很容易檢查ghc-core工具。

-- Test.hs 
main = putStrLn $ "Hello " ++ "world" 

,當我們運行ghc-core Test.hs

[1 of 1] Compiling Main    (Test.hs, Test.o) 

==================== Tidy Core ==================== 
Result size of Tidy Core = {terms: 19, types: 23, coercions: 9} 

main2 :: [Char] 
[GblId, 
Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=False, 
     ConLike=False, WorkFree=False, Expandable=False, 
     Guidance=IF_ARGS [] 60 0}] 
main2 = unpackCString# "Hello world" 

... 

,看到該字符串已在覈心中間語言被合併。


編輯:爲了強調我同意與其他答案,只是因爲這個特定的程序與合併後的字符串核心轉儲不保證編譯器會做的所有字符串。遵守Haskell規範並不意味着事情如何編譯。

+0

仔細關於使用「核心轉儲」來打印中間核心代碼:-) – David

+0

我可能已經傳達了一種人爲的感覺,它是如何輕鬆地偷看核心並瞭解事情的表現如何......但!我經常發現它並不那麼困難。剛開始時令人望而生畏。 –

19

Haskell 2010保證在編譯時連接字符串文字嗎?

運行時效率遠離Haskell2010的範圍。我們不想因爲速度緩慢而禁止實驗性實施。

另外,說在編譯期間應該做什麼會給口譯員帶來麻煩,比如擁抱。

最後,給予執行者一些自由是有用的。也許在一些奇怪的情況下,預先計算字符串實際上會更快一些?

Haskell 2010僅在錯誤的情況下討論編譯時間。 (例如類型錯誤保證是編譯時。)

4

我不這樣做,哈斯克爾保證。可能會有像ghc這樣的編譯器進行這種優化,但沒有標準保留這一點。所以在未來的版本中可能會發生這種優化可能不會發生。

爲什麼不使用模板哈斯克爾,如果你真的想保證它在編譯時完成。下面的例子是在GHC測試,但我認爲你可以把它在其他編譯器工作太:

在一個模塊文件,你可以有這樣的

module Concat where 
import Language.Haskell.TH 

(<++>) :: String -> String -> ExpQ 
(<++>) x y = stringE (x ++ y) 

然後在該文件中,你需要以實際代碼通過使用串聯的字符串是在編譯時產生-ddump-splices做編譯時間串聯

{-# LANGUAGE TemplateHaskell #-} 
import Concat 

f = $("This is a very long string" <++> 
     "which spans over several lines") 

你甚至可以檢查GHC。

+5

還有[Poor many's here document](http://www.haskell.org/haskellwiki/Poor_man's_here_document),它使用拼接而不是內聯運算符。 –

+0

@tel謝謝。這看起來好多了。 – Satvik