简体   繁体   English

Haskell 递归 - 如何用原始值调用另一个 function 但只有一次

[英]Haskell Recursion - How to call another function with original values but only once

I am trying to figure out how I can recursively define a function while also calling a second function at one of the original integer max values.我想弄清楚如何递归定义 function,同时在原始 integer 最大值之一处调用第二个 function。 I don't want to add another integer input however I want to call the second function with the integer from the first function (but only once) I would happily also shorten this down into 1 function if that's better/possible我不想添加另一个 integer 输入但是我想用第一个 function 中的 integer 调用第二个 function(但只有一次)如果更好/可能的话,我也很乐意将其缩短为 1 function

testFunction::Int->String
testFunction s 
 |s == 0 = ""
 |otherwise = "abc" ++ testFunction (s-1) ++ testFunction2 s

testFunction2::Int->String
testFunction2 s
 |s == 0 = "" 
 |otherwise = testFunction2 (s-1)++"cba"

For example, this will call testFunction recursively and then because it does this it will call testFunction2 multiple times with s-1 in the main function. I only want the content of testFunction2 to be called once and only with the initial value of S without adding any other int inputs.例如,这将递归调用 testFunction,然后因为它这样做,它会在主 function 中使用 s-1 多次调用 testFunction2。我只希望 testFunction2 的内容被调用一次,并且只使用 S 的初始值而不添加任何其他 int 输入。 Say I called 'testFunction 2' it currently outputs 'abcabccbacbacba', however I only want cba outputted twice so I really want 'abcabccbacba' Thank you for the help:)假设我调用了“testFunction 2”,它当前输出“abcabccbacbacba”,但是我只希望 cba 输出两次,所以我真的想要“abcabccbacba”谢谢你的帮助:)

The usual way of doing this sort of thing is to break the function up into some non-recursive "top-level" processing and a recursive helper, usually defined in a where clause and given a generic name like go or step or loop .做这种事情的通常方法是将 function 分解成一些非递归的“顶级”处理和一个递归助手,通常在where子句中定义并给出一个通用名称,如gosteploop

So, you might write:所以,你可以这样写:

testFunction :: Int -> String
testFunction s
  | s == 0 = ""
  | otherwise
    -- here's the top-level processing
    = "abc" ++ go (s-1) ++ testFunction2 s
  where
    -- here's the recursive helper
    go s | s == 0 = ""
         | otherwise = "abc" ++ go (s-1)

In this example, this results in some repeated code.在这个例子中,这会导致一些重复的代码。 You can refactor to remove some of the duplication, though it may be difficult to remove all of it (eg, the s == 0 handling):您可以重构以删除一些重复项,尽管可能很难删除所有重复项(例如, s == 0处理):

testFunction :: Int -> String
testFunction s
  | s == 0 = ""
  | otherwise = go s ++ testFunction2 s
  where
    go s | s == 0 = ""
         | otherwise = "abc" ++ go (s-1)

Your function looks like an equivalent of你的 function 看起来相当于

testFunction s = concat (replicate s "abc") ++
                 concat (replicate (s*(s+1)`div`2) "cba")

and you apparently want你显然想要

testFunction s = concat (replicate s "abc") ++ 
                 concat (replicate s "cba")

So, there it is, shortened down into one function. But it's not recursive (it's not clear to me if that's a hard requirement here, or not).所以,它就是这样,缩短为一个 function。但它不是递归的(我不清楚这是否是一个硬性要求)。

It could also be written也可以写成

 = concat (replicate s "abc"  ++  replicate s "cba")
 = concat $ concatMap (replicate s) ["abc", "cba"]
 = ["abc", "cba"] >>= replicate s >>= id

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

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