Haskell 中递归调用的递减值
Decremented value called in the recursion in Haskell
所以,我有这个函数可以将给定列宽的文本向左对齐。我已经修复了它的一些问题,但我无法让它在调用时不使用递减的参数,而是return到n
的起始值。这是我的代码:
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!"
这里有一个例子,最后一行的 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 .
有什么想法吗?
是的,一旦你用一个新值 n 再次调用 f,它就没有办法引用 n 的旧值,除非你显式地传递它。一种方法是像您一样拥有一个带有宽度参数的内部递归函数,但它可以在需要时将参数引用到外部函数。
例如,类似的东西有效:
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!"
这里width
是计算中的当前宽度,而n
始终不变,这使得f'
在新行的开始重新计算时可以使用它.
这只是回答你的确切问题。一个很好的练习是用更惯用的 Haskell 重写代码,避免一些性能缺陷,比如过度依赖 !!
。但首先让它工作,然后让它优雅!
所以,我有这个函数可以将给定列宽的文本向左对齐。我已经修复了它的一些问题,但我无法让它在调用时不使用递减的参数,而是return到n
的起始值。这是我的代码:
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!"
这里有一个例子,最后一行的 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 .
有什么想法吗?
是的,一旦你用一个新值 n 再次调用 f,它就没有办法引用 n 的旧值,除非你显式地传递它。一种方法是像您一样拥有一个带有宽度参数的内部递归函数,但它可以在需要时将参数引用到外部函数。 例如,类似的东西有效:
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!"
这里width
是计算中的当前宽度,而n
始终不变,这使得f'
在新行的开始重新计算时可以使用它.
这只是回答你的确切问题。一个很好的练习是用更惯用的 Haskell 重写代码,避免一些性能缺陷,比如过度依赖 !!
。但首先让它工作,然后让它优雅!