我正在Haskell中编写一个非常简单的程序,它要求用户输入一个名称,然后根据该名称显示一些文本。我可以让程序工作,但是当用户输入我的猫的名字时,我想显示猫的ASCII图片。我想要像
这样的东西 ^ - ^
( . . )
=>;<=
/ \
| |
我的&#34;让我们看看它是否有效&#34;方法是使用putStrLn。这不起作用。我能做什么?谢谢。我的尝试
if name == "cat"
then putStrLn (" ^ - ^
( . . )
=>;<=
/ \
| |")
答案 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"