Programing

Haskell에서 여러 줄 문자열을 어떻게 작성할 수 있습니까?

crosscheck 2020. 12. 28. 21:49
반응형

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.

다음과 같이 여러 줄 문자열을 작성할 수 있습니다.

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

얼마 전에 확장을 사용하는 여러 줄 문자열 및 보간 문제를 해결하기 위해 "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
  }
}

Notice how it neatly preserved the indentation levels of lines the variable placeholders were at. The standard interpolators would have messed all the whitespace and produced something like the following instead:

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

In Haskell you can type multiline strings by ending it with a backslash \ and beginning the newline with another \, just like so :

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

I don't believe that Haskell has an easy way to do this without resorting to quasiquoting or something else. However you can mostly get what you want by using the unlines function like below. However this will result in a newline after your last line, which you may or may not care about.

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

Many times this facality is referred to as heredocs. Haskell does not have heredocs.

However, there are several packages that use GHC's QuasiQuotes extensions to achieve this.

Here is one I use: http://hackage.haskell.org/package/interpolatedstring-perl6-0.9.0/docs/Text-InterpolatedString-Perl6.html

Your example would look like:

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

Quasiquotation examplete presented in Multi-line strings in Haskell.

{-# 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 is my favorite for the purpose yet.

ReferenceURL : https://stackoverflow.com/questions/22918837/how-can-i-write-multiline-strings-in-haskell

반응형