简体   繁体   English

在Haskell递归中调用的递减值

[英]Decremented value called in the recursion in Haskell

So, I have this function that aligns the text to the left for a given column width. 因此,我有此功能,可将文本向左对齐给定的列宽。 I have already fixed some of its problems, but I am unable to make it not use the decremented parameter once it is called, but to return to the starting value of n . 我已经解决了它的一些问题,但是一旦调用它,我无法使它不使用减量的参数,而是返回到n的起始值。 Here is my code: 这是我的代码:

 f n s
   | length s <= n = take (length s) s ++ "\n"                    
   | n >= (maximum . map length . words) s =                   
       if s !! n == ' ' || s !! n == '\t' || s !! n == '\n'
       then take n s ++ "\n" ++ f n (drop (n+1) s)                   
       else f (n - 1) s          --Here once called for some n-1 it proceeds to call it from then on only for it or even smaller n
   | otherwise = error "Try bigger width!"

Here is an example ,where the to on the last line should be really on the second line: 这是一个示例,其中最后一行上的to实际上应该在第二行上:

*Main> let s = "This miscellaneous items are starting to get shitty ."
*Main> putStr $ f 22 s
This miscellaneous
items are starting
to get shitty .

Any ideas? 有任何想法吗?

Yes, once you call again f with a new value of n, it has no way to reference the old value of n unless you pass it explicitly. 是的,再次使用新值n调用f时,除非显式传递它,否则无法引用旧值n。 One way to do it is to have an internal recursive function with its width parameter, as you have, but that can reference the parameter to the outer function when needed. 一种实现方法是,如您所愿,使用内部递归函数及其width参数,但是可以在需要时将该参数引用到外部函数。 For example, something like that works: 例如,类似的方法有效:

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

Here width is the current width in the calculation, and n is always unchanged, which allows f' to use it when resetting the calculation at the start of a new line. 这里width是计算中的当前宽度, n始终不变,这使得f'在新行的开头重置计算时可以使用它。

That's only answering your precise question. 那只是回答您的确切问题。 A good exercise would then be to rewrite your code in what would be more idiomatic Haskell, avoiding some performance pitfalls like the overreliance on !! 一个不错的练习就是用更加惯用的Haskell重写代码,避免一些性能陷阱,例如对!!的过度依赖!! . But first get it working, and then make it elegant! 但是首先要使其工作,然后使其优雅!

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

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