对于几个项目,我需要将长字符串嵌入到Haskell源代码中。
显而易见的方法是unlines
一系列行。但是,阅读和维护这个很麻烦。
cCode :: String
cCode = unlines [
"int main(int argc*, char** argv)",
" doStuff();",
"}"]
有没有办法可以在没有任何开销的情况下嵌入字符串(如上图所示的列表)甚至文件? TemplateHaskell / Quasi-quotation是走这里的方式吗?
注意:此问题已在Q& A表单中得到解答。因此,它没有显示任何研究工作。
答案 0 :(得分:5)
可以使用QuisQuotation描述in this blogpost written by me。
第1步:创建一个模块(我们将其称为StringEmbed.hs
,其中包含所需的功能
module StringEmbed(embedStr, embedStrFile) where
import Language.Haskell.TH
import Language.Haskell.TH.Quote
embedStr :: QuasiQuoter
embedStr = QuasiQuoter { quoteExp = stringE,
quotePat = undefined,
quoteDec = undefined,
quoteType = undefined }
embedStrFile :: QuasiQuoter
embedStrFile = quoteFile embedStr
请注意,由于TH的特殊性, 可能只是将这些功能复制到您使用它们的模块中。
步骤2a:在您的模块中,嵌入字符串:
{-# LANGUAGE QuasiQuotes #-}
import StringEmbed
cCode :: String
cCode = [embedStr|
int main(int argc, char** argv) {
doStuff();
}
|]
请注意,您只需添加QuasiQuotes
LANGUAGE
pragma。此技术不需要TemplateHaskell
。
因为QuasiQuotes是使用|]
分隔的,所以你不能在准引用字符串中的任何地方使用该字符序列。
步骤2b:您可以轻松嵌入文件。我们假设文件code.c
包含您要嵌入的字符串。
{-# LANGUAGE QuasiQuotes #-}
import StringEmbed
cFooter :: String
cFooter = [embedStrFile|code.c|]
或者您可以使用众多haskell库中的一个而不是StringEmbed.hs
,例如heredoc(感谢Ørjan Johansen提示!)
{-# LANGUAGE QuasiQuotes #-}
import Text.Heredoc
cCode :: String
cCode = [here|
int main(int argc, char** argv) {
doStuff();
}
|]
答案 1 :(得分:3)
您可以使用带有间隙的多行字符串。它可能不如quasiquoters那么顺利,但它是标准的Haskell。
cCode :: String
cCode = "\
\int main(int argc*, char** argv)\n\
\ doStuff();\n\
\}\n\
\"