Подтвердить что ты не робот

Содержит ли Haskell строковые литералы во время компиляции?

Предоставляет ли Haskell 2010 возможность конкатенации строковых литералов во время компиляции?

Если у меня

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

компилятор рассматривает его как

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

Я хочу, чтобы мои исходные строки имели длину менее 80 символов, если это возможно, но я не хочу вводить неэффективность во время выполнения.

4b9b3361

Ответ 1

Используйте пробел - последовательность одного или нескольких символов пробела между обратными косыми чертами:

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

эквивалент нулевой ширины \&, полезный для разделения числовых экранов от цифровых символов:

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

Ответ 2

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 вовсе не означает, что вещи компилируются.

Ответ 3

Предоставляет ли Haskell 2010 возможность конкатенации строковых литералов во время компиляции?

Нет.

Эффективность времени выполнения далеко от объема Haskell2010. Мы не хотим запрещать экспериментальные реализации только потому, что они медленны.

Кроме того, высказывание того, что должно быть сделано во время компиляции, вызовет проблемы для интерпретаторов, таких как Hugs.

Наконец, полезно дать некоторую свободу разработчикам. Возможно, в некоторых странных обстоятельствах было бы быстрее не прекомпотировать строку?

Haskell 2010 говорит о времени компиляции только в контексте ошибок. (Например, ошибки типа гарантируются как время компиляции.)

Ответ 4

Я не уверен, что это 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")

Вы даже можете проверить ghc, используя -ddump-splices, что во время компиляции создается конкатенированная строка.