如何使用`putStrLn`打印多行字符串?

时间:2017-04-09 14:49:22

标签: haskell

我正在Haskell中编写一个非常简单的程序,它要求用户输入一个名称,然后根据该名称显示一些文本。我可以让程序工作,但是当用户输入我的猫的名字时,我想显示猫的ASCII图片。我想要像

这样的东西
  ^  -  ^
 ( .   . )
   =>;<=
  /     \
 |       |

我的&#34;让我们看看它是否有效&#34;方法是使用putStrLn。这不起作用。我能做什么?谢谢。我的尝试

if name == "cat"
    then putStrLn ("      ^  -  ^
                         ( .   . )
                           =>;<=
                          /     \
                         |       |")

2 个答案:

答案 0 :(得分:6)

李问“以什么方式不putStrLn工作?”你回答说:

if name == "cat"
    then putStrLn ("      ^  -  ^
                         ( .   . )
                           =>;<=
                          /     \
                         |       |")

您应该包含错误消息。将其置于顶级函数(test name = ...)中,代码无法编译:

so.hs:3:38: error:
    lexical error in string/character literal at character '\n'

这是因为你不能在Haskell字符串文字中有换行符。 Haskell中的多行字符串需要特殊的转义(每行的开头和结尾都有反斜杠。你的ascii艺术中已经有一个未转义的反斜杠本应该被转义,所以我们也会修复它:

 test name =
        if name == "cat"
    then putStrLn ("      ^  -  ^\n\
                   \     ( .   . )\n\
                   \       =>;<=\n\
                   \      /     \\\n\
                   \     |       |")

现在我们得到另一个错误,因为在Haskell中if语句更像是三元运算符,因此需要一个else分支来保持良好的类型。生成的代码是:

test name =
        if name == "cat"
        then putStrLn ("      ^  -  ^\n\
                       \     ( .   . )\n\
                       \       =>;<=\n\
                       \      /     \\\n\
                       \     |       |")
        else return ()

或者,您可以使用准引用来获得更漂亮的多行字符串。这需要string-qq包和quasiquotes语言扩展。扩展名的语法为[|<quoter name>|<string>|],string-qq包为字符串提供了名为s的引号:

{-# LANGUAGE QuasiQuotes #-}
import Data.String.QQ
import Control.Monad (when)

test2 name =
    when (name == "cat") $ putStrLn [s|
      ^  -  ^
     ( .   . )
       =>;<=
      /     \\
     |       ||]

答案 1 :(得分:5)

这是另一种替代方案,我有时会使用它:

putStr $ unlines 
  [ "      ^  -  ^"
  , "     ( .   . )"
  , "       =>;<="
  , "      /     \\"
  , "     |       |"
  ]

unlines是一个标准函数,它接受一个字符串列表并连接它们,并在每个字符串后插入换行符(包括最后一个 - 因此我使用putStr代替)。

> unlines ["abc", "def", "ghi"]
"abc\ndef\nghi\n"