我在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的第二行。类型decalaration导致错误。需要帮助
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
答案 0 :(得分: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解释器在每次输出后添加额外的换行符。)
答案 1 :(得分:2)
您可能正在使用print x
打印字符串,这相当于putStrLn (show x)
。 show x
正在将换行符转换为可读字符\
和n
。如果您不想在字符串的末尾添加换行符,则需要使用putStrLn x
代替putStr x
。
除非是故意的,否则您还应删除换行符周围的单引号。
答案 2 :(得分:1)
重新更新:您的类型声明是正确的,formatLines
的其余部分是错误的。
formatLines :: [(Name,Price)]->IO()
formatLines [] = return ()
formatLines (a:x) = formatLines x >> formatLine a
更简洁的写作方式
formatLines :: [(Name,Price)]->IO()
formatLines = mapM_ formatLine . reverse
答案 3 :(得分: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