Haskell:递归问题
我正在尝试将文本格式设置为矩形;目前我已经能够将其正确左对齐,但最后一行并没有尽可能地延伸。
我正在尝试计算最佳字段宽度,以最大限度地减少或完全消除这种情况。
我完全被困住了。下面的代码展示了相关的功能。此刻它陷入了无限循环。 我哪里错了?
顺便说一句,调试 Haskell 代码的最佳方法是什么? (是的,我对此很陌生。)
optimumFieldWidth 应该比较线长度,直到顶线的长度等于底线的长度,然后返回导致此结果为真的字段宽度。
module Main where
import System
import Data.List
main = do
(f:_) <- getArgs
xs <- getContents
putStr (show (bestFieldWidth maxLineLength xs))
bestFieldWidth :: Int -> String -> Int
bestFiledWidth _ [] = 0
bestFieldWidth lineLength xs
| length (last input) == length (head input) = lineLength
| otherwise = bestFieldWidth (length (head (rect (lineLength-1) xs))) xs
where input = lines xs
rect :: Int -> String -> [String]
rect _ [] = []
rect lineLength xs
| length input <= len = [input]
| otherwise = take len input : rect len (drop len input)
where input = trim xs
len = bestFieldWidth lineLength xs
maxLineLength :: Int
maxLineLength = 40
感谢所有回复。谢谢。
I am trying to format text to be in the shape of a rectangle; currently I have been able to get it properly left justified, but the last line does not extend as far as possible.
I am trying to calculate the optimum field width in order to minimise or remove this entirely.
I am totally stuck. The code below shows the relevant functions. At the moment it gets stuck in an infinite loop.
Where am I going wrong?
On a side note, what is the best way of debugging Haskell code?
(Yes, I'm very new to this.)
optimumFieldWidth is supposed to compare line lengths until the length of the top line is equal to that of the bottom line, then return the field width which causes this to be true.
module Main where
import System
import Data.List
main = do
(f:_) <- getArgs
xs <- getContents
putStr (show (bestFieldWidth maxLineLength xs))
bestFieldWidth :: Int -> String -> Int
bestFiledWidth _ [] = 0
bestFieldWidth lineLength xs
| length (last input) == length (head input) = lineLength
| otherwise = bestFieldWidth (length (head (rect (lineLength-1) xs))) xs
where input = lines xs
rect :: Int -> String -> [String]
rect _ [] = []
rect lineLength xs
| length input <= len = [input]
| otherwise = take len input : rect len (drop len input)
where input = trim xs
len = bestFieldWidth lineLength xs
maxLineLength :: Int
maxLineLength = 40
All responses are appreciated. Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我想我应该把实际的解决方案放在这里,以防其他疯子希望这样做。
请记住,它是由一个白痴编写的,因此它可能不是最优雅的解决方案。
I thought I'd put the actual solution here in case any other nutters wish to do this.
Please bear in mind that it was written by a moron so it probably isn't the most elegant solution.
似乎条件
length (last input) == length (head input)
一旦为 false,在随后对area
的调用中永远不会变为 true,从而使该函数始终采用 < code>otherwise 分支并继续使用相同的xs
值以及input
无限期地调用自身。造成这种情况的可能原因是您使用了lines函数,该函数用换行符分割字符串,其方式不依赖于lineLength,并且与您在
rect
函数。It seems that the condition
length (last input) == length (head input)
once false never goes true in subsequent calls toarea
, thus making this function always take theotherwise
branch and keep calling itself indefinitely with the same values ofxs
and thusinput
.Possible cause of this is that you use the
lines
function, which splits a string with newline characters, in a way not dependent onlineLength
and inconsistent with your line-splitting in therect
function.为了回答你的旁注,这里有一个关于调试 Haskell 的优秀指南: http://cgi.cse.unsw.edu.au/~dons/blog/2007/11/14
还有 Debug.Trace,它允许您插入打印语句。它当然应该只在调试时使用,因为它会使你的函数产生副作用。
http://hackage.haskell.org/packages /archive/base/latest/doc/html/Debug-Trace.html
In answer to your side note, here is an excellent guide to debugging Haskell: http://cgi.cse.unsw.edu.au/~dons/blog/2007/11/14
There's also Debug.Trace, which allows you to insert print statements. It should of course only be used while debugging, because it makes your function have side effects.
http://hackage.haskell.org/packages/archive/base/latest/doc/html/Debug-Trace.html