在Haskell中换行 - 更新

3

我有一些Haskell的函数,需要打印每周的销售额,每个销售额都应该显示在新的一行。但是它并不像我期望的那样工作。我的问题在于换行符 '\n'。

代码:

printWeeks :: Int->String
printWeeks 0 = printWeek 0
printWeeks x  = printWeeks(x-1) ++ printWeek x 

printWeek :: Int->String
printWeek x = show(x)  ++  "  " ++ stars (sales x) ++ "'\n'"

我尝试了许多方法,但换行符并没有按预期工作。 所有内容都打印在同一行上,这不是我想要的。
需要帮助吗?
谢谢
更新
以下内容由于编译错误而无法工作。 错误来自formatLines的第二行。 类型声明导致错误。 需要在这里寻求帮助。
formatLine :: (Name,Price)->IO()
formatLine (a,b) = putStrLn (a ++ dots ++ p) 
                   where
                   x=(length a)
                   p=(formatPence b)
                   y=length p  
                   z=lineLength-(x+y)
                   dots = printDots z 


formatLines :: [(Name,Price)]->IO()
formatLines []= ""
formatLines (a:x) = formatLines x ++ formatLine a

1
"'\n'" 是一个由三个字符组成的字符串 -- 一个单引号、一个换行符和另一个单引号。你需要的是 "\n",它是一个只包含一个换行符的字符串;该字符串是列表 ['\n'],其中包含的是 '\n'。你的字符串是 ['\'','\n','\''] - applicative
4个回答

3
你应该使用 ++ "\n" 来添加一个换行符到输出中;你当前的代码会先添加 ',然后是一个换行符,再接着是另一个 '
正如 @marcog 所指出的那样,一定要使用 putStr 来打印它(或者根本不添加换行符并使用 putStrLn)。示例:
Hugs> putStr (show 4 ++ "\n")
4

Hugs> putStrLn (show 4 ++ "\n")
4


Hugs> print (show 4 ++ "\n")
"4\n"

(请注意,Hugs解释器在每个输出后添加额外的换行符。)

谢谢您的回复。我该如何在函数定义之前声明类型? - Kap

2
你可能是通过使用“print x”的方式输出字符串,这等同于“putStrLn(show x)”。 “show x”将换行符转换为可读字符“\”和“n”。你需要改用“putStrLn x”,或者如果你不想在字符串末尾添加换行符,则可以使用“putStr x”。
另外,除非这是有意为之,否则应该去掉你在换行符周围的单引号。

谢谢您的回复。我该如何声明类型?我有类似以下的前两行代码,但它们报错了:formatLines :: [(Name,Price)]->IO() formatLines []= "" - Kap
@Kap 抱歉,我对 Haskell 的知识不足以帮助你。我建议你提出一个新的问题。 - moinudin

1
关于您的更新:您的类型声明是正确的,问题出在formatLines的其余部分。
formatLines :: [(Name,Price)]->IO()
formatLines [] = return ()
formatLines (a:x) = formatLines x >> formatLine a

更简洁的写法是:

formatLines :: [(Name,Price)]->IO()
formatLines = mapM_ formatLine . reverse

1

为什么这么多操作都在 IO 标题下进行,有点像谜一样。这可能有点啰嗦。我无法确定 lineLength 是从哪里来的,所以我将其作为参数。

formatLine :: Int -> (Name,Price) -> String
formatLine linelength (name, price) =  name ++ dotfill ++ showprice 
  where 
  showprice :: String
  showprice = formatPence price
  extra :: Int
  extra = linelength - length (name ++ showprice)
  dotfill :: String
  dotfill = replicate extra '.'

formatLines :: Int -> [(Name, Price)] -> String
formatLines linelength []= ""
formatLines linelength (first:rest) = 
  (formatLine linelength first ++ "\n") ++ formatLines linelength rest

standardPrint :: [(Name, Price)] -> IO ()
standardPrint listing = putStrLn (formatLines 50 listing)

fileAwayPrices :: FilePath -> [(Name,Price)] -> IO()
fileAwayPrices filename listing = writeFile filename (formatLines 70 listing)

testlist :: [(Name,Price)]
testlist = [("oats",344),("barley", 299),("quinoa",599)]

-- *Main> standardPrint testlist
-- oats...........................................344
-- barley.........................................299
-- quinoa.........................................599


type Name = String
type Price = Integer
formatPence n = show n

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接