简体   繁体   English

递归函数的停止条件-Haskell

[英]Stopping condition on a recursive function - Haskell

So, I have this function which aims to align the text on the left without cutting words(only white spaces). 因此,我具有此功能,旨在使文本在左侧对齐而不剪切单词(仅保留空白)。 However my problem is that I cannot find a stopping condition of the function and it goes infinitely. 但是,我的问题是我找不到该函数的停止条件,并且它无限进行。

f n "" = ""          --weak condition
f n s  = if n >= ((maximum . map length . words) s) then if (s !! n == ' ' || s !! n == '\t' || s !! n == '\n') 
                                                    then take n s ++ "\n" ++ (f n ( drop n s)) else f (n-1) s 
                                                    else error "Try bigger width!"

Well, basically if the n is smaller than the longest word then it prompts error, else it ''cuts'' the string in the white spaces until it reaches a not white space character, then it calls itself recursively for n-1 . 好吧,基本上,如果n小于最长的单词,则提示错误,否则它会在空白中“剪切”字符串,直到到达非空白字符为止,然后对n-1递归调用。 I use also putStr to avoid "\\n" in the output. 我也使用putStr来避免输出中的“ \\ n”。

However, as I already said the stopping condition is too weak or non-existent. 但是,正如我已经说过的,停止条件太弱或根本不存在。 If there are other flows in the code or possible optimizations(eg less ifs), please tell. 如果代码中还有其他流程或可能的优化措施(例如,较少的ifs),请告知。

Your code doesn't handle the case where a line is shorter than the maximum length. 您的代码无法处理行短于最大长度的情况。

This is somewhat obscured by another bug: n is decremented until a whitespace is found, and then f is called recursively passing this decremented value of n , effectively limiting all subsequent lines to the length of the current line. 这在某种程度上被另一个错误所掩盖:将n递减直到找到空白,然后调用f递归传递n递减值,从而有效地将所有后续行限制为当前行的长度。

(Also, you might want to drop n + 1 characters from s so the original whitespace isn't included in the output.) (此外,您可能希望从s删除n + 1字符,以便在输出中不包含原始空格。)

You can avoid ifs by using patterns: 您可以使用模式来避免ifs:

f n "" = "" -- weak condition
f n s
  | n >= (maximum . map length . words) s =
      if s !! n == ' ' || s !! n == '\t' || s !! n == '\n'
      then take n s ++ "\n" ++ f n (drop n s)
      else f (n - 1) s
  | otherwise = error "Try bigger width!"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM