简体   繁体   English

Haskell在编译时是否连接了字符串文字?

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

Does Haskell 2010 guarantee to concatenate String literals at compile time? Haskell 2010是否保证在编译时连接字符串文字?

If I have 如果我有

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

does the compiler treat it as 编译器会将其视为

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

I want to keep my source lines less than 80 characters long if possible, but I don't want to introduce run-time inefficiency. 如果可能的话,我想保持我的源行长度不超过80个字符,但我不想引入运行时效率低下。

Haskell 2010 guarantees that it's denotationally equivalent to the merged string, but has nothing to say about how it should be compiled. Haskell 2010保证它在表示上等同于合并的字符串,但没有什么可说的如何编译。 It's easy enough to check with the ghc-core tool, though. 但是,使用ghc-core工具检查很容易。

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

and when we run ghc-core Test.hs 当我们运行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"

...

and see that the string has been merged in the Core intermediate language. 并看到该字符串已在Core中间语言中合并。


Edit: To emphasize my agreement with other answers, just because this particular program has a core dump with the merged string does not guarantee that the compiler will do it for all strings. 编辑:为了强调我与其他答案的一致,仅仅因为这个特定的程序有一个带有合并字符串的核心转储,并不能保证编译器会为所有字符串执行此操作。 Being compliant with the Haskell spec doesn't imply much at all about how things get compiled. 遵守Haskell规范并不意味着事情如何编译。

Does Haskell 2010 guarantee to concatenate String literals at compile time? Haskell 2010是否保证在编译时连接字符串文字?

No. 没有。

Run-time efficiency is far away from the scope of Haskell2010. 运行时效率远离Haskell2010的范围。 We don't want to ban experimental implementations just because they are slow. 我们不想仅仅因为它们很慢而禁止实验性实施。

Also, saying what should be done during the compile time would cause troubles for interpreters, such as Hugs. 另外,说在编译期间应该做什么会给解释器带来麻烦,例如Hugs。

Finally, it is useful to give some freedom to implementors. 最后,为实现者提供一些自由是有用的。 Perhaps under some strange circumstances it would be actually faster not to precompute the string? 也许在某些奇怪的情况下,预先计算字符串实际上会更快?

Haskell 2010 talks about compile time only in the context of errors. Haskell 2010仅在错误的背景下讨论编译时间。 (Eg type errors are guaranteed to be compile-time.) (例如,类型错误保证是编译时。)

Use a gap—a sequence of one or more whitespace characters between backslashes: 使用间隙 - 反斜杠之间的一个或多个空白字符序列:

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

The zero-width equivalent is \\& , useful for separating numeric escapes from digit characters: 零宽度等价物是\\& ,用于将数字转义符与数字字符分开:

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

I don't this haskell guarantees that. 我没有这个haskell保证。 There might be come compilers like ghc performing this optimisation but there is no standard preserving this. 可能会有像ghc这样的编译器执行此优化,但没有标准保留此功能。 So it might happen that in a future version this optimisation might not occur. 因此,在将来的版本中可能不会发生此优化。

Why don't you use Template Haskell if you really want to guarantee that it is done at compile time. 如果你真的想保证它是在编译时完成的,为什么不使用Template Haskell。 Following example is tested on ghc but I think you can make it work on other compilers too: 以下示例在ghc上进行了测试,但我认为您也可以将其用于其他编译器:

In a module file you can have a code like this 在模块文件中,您可以拥有这样的代码

module Concat where
import Language.Haskell.TH

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

Then in the file which you require to actually do the compile time concatenation 然后在您需要实际执行编译时连接的文件中

{-# LANGUAGE TemplateHaskell #-}
import Concat

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

You can even check in ghc by using -ddump-splices that the concatenated string is generated at compile time. 您甚至可以使用-ddump-splices来检查ghc,即在编译时生成连接字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM