如何在Haskell中编写多行字符串?

时间:2014-04-07 17:10:52

标签: haskell

假设我有这个带换行符的字符串文字:

file :: String
file = "the first line\nthe second line\nthe third line"

有没有办法像这样写呢?

file :: String
file = "the first line
        the second line
        the third line"

上述尝试导致此错误:

factor.hs:58:33:
    lexical error in string/character literal at character '\n'
Failed, modules loaded: none.

6 个答案:

答案 0 :(得分:77)

您可以编写多行字符串,如此

x = "This is some text which we escape \
      \   and unescape to keep writing"

打印为

"This is some text which we escape   and unescape to keep writing"

如果您希望将其打印为两行

x = "This is some text which we escape \n\
      \   and unescape to keep writing"

打印为

This is some text which we escape
    and unescape to keep writing

答案 1 :(得分:34)

前段时间我发布了一个名为"neat-interpolation"的库来解决使用QuasiQoutes扩展名的多行字符串和插值问题。它比竞争对手的主要优势是对空白的智能管理,它负责内插的多线字符串。以下是它如何工作的一个例子。

执行以下操作:

{-# LANGUAGE QuasiQuotes, OverloadedStrings #-}

import NeatInterpolation (text)
import qualified Data.Text.IO

f :: Text -> Text -> Text
f a b = 
  [text|
    function(){
      function(){
        $a
      }
      return $b
    }
  |]

main = Data.Text.IO.putStrLn $ f "1" "2"

将产生这一点(注意与声明的缩进相比减少的缩进):

function(){
  function(){
    1
  }
  return 2
}

现在让我们用多行字符串参数测试它:

main = Data.Text.IO.putStrLn $ f 
  "{\n  indented line\n  indented line\n}" 
  "{\n  indented line\n  indented line\n}" 

我们得到了

function(){
  function(){
    {
      indented line
      indented line
    }
  }
  return {
    indented line
    indented line
  }
}

注意它如何巧妙地保留了变量占位符所在行的缩进级别。标准内插器会弄乱所有空格并产生如下内容:

    function(){
      function(){
        {
  indented line
  indented line
}
      }
      return {
  indented line
  indented line
}
    }

答案 2 :(得分:17)

在Haskell中,您可以通过以反斜杠\结尾并使用另一个\开始换行来输入多行字符串,就像这样:

file :: String
file = "the first line\n\  
    \the second line\n\  
    \the third line\n"  

答案 3 :(得分:10)

我不相信Haskell有一种简单的方法可以做到这一点,而无需借助于quasiquoting或其他东西。但是,你可以通过使用如下所示的unlines函数获得你想要的东西。但是,这会导致在您的最后一行之后换行,您可能会或可能不会关心。

file :: String
file = unlines [
    "the first line",
    "the second line",
    "the third line"
    ]

答案 4 :(得分:8)

很多时候,这种方式被称为heredocs。 Haskell没有heredocs。

但是,有几个软件包使用GHC的QuasiQuotes扩展来实现这一目标。

我使用的是http://hackage.haskell.org/package/interpolatedstring-perl6-0.9.0/docs/Text-InterpolatedString-Perl6.html

您的示例如下:

file = [q|
the first line
the second line
the third line
|]

答案 5 :(得分:1)

Multi-line strings in Haskell中提供的Quasiquotation示例。

{-# LANGUAGE QuasiQuotes #-}
import Text.RawString.QQ

multiline :: String
multiline = [r|<HTML>
<HEAD>
<TITLE>Auto-generated html formated source</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
</HEAD>
<BODY LINK="800080" BGCOLOR="#ffffff">
<P> </P>
<PRE>|]

raw-strings-qq是我最喜欢的目的。