簡體   English   中英

Haskell在編譯時是否連接了字符串文字?

[英]Does Haskell concatenate String literals at compile time?

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

如果我有

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

編譯器會將其視為

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

如果可能的話,我想保持我的源行長度不超過80個字符,但我不想引入運行時效率低下。

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"

...

並看到該字符串已在Core中間語言中合並。


編輯:為了強調我與其他答案的一致,僅僅因為這個特定的程序有一個帶有合並字符串的核心轉儲,並不能保證編譯器會為所有字符串執行此操作。 遵守Haskell規范並不意味着事情如何編譯。

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

沒有。

運行時效率遠離Haskell2010的范圍。 我們不想僅僅因為它們很慢而禁止實驗性實施。

另外,說在編譯期間應該做什么會給解釋器帶來麻煩,例如Hugs。

最后,為實現者提供一些自由是有用的。 也許在某些奇怪的情況下,預先計算字符串實際上會更快?

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

使用間隙 - 反斜杠之間的一個或多個空白字符序列:

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

零寬度等價物是\\& ,用於將數字轉義符與數字字符分開:

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

我沒有這個haskell保證。 可能會有像ghc這樣的編譯器執行此優化,但沒有標准保留此功能。 因此,在將來的版本中可能不會發生此優化。

如果你真的想保證它是在編譯時完成的,為什么不使用Template Haskell。 以下示例在ghc上進行了測試,但我認為您也可以將其用於其他編譯器:

在模塊文件中,您可以擁有這樣的代碼

module Concat where
import Language.Haskell.TH

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

然后在您需要實際執行編譯時連接的文件中

{-# LANGUAGE TemplateHaskell #-}
import Concat

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

您甚至可以使用-ddump-splices來檢查ghc,即在編譯時生成連接字符串。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM