在递归构建列表时,如何在头部使用列表的创建元素?

时间:2012-05-31 09:36:00

标签: recursion f# functional-programming

我正在尝试在F#中编写一个引导算法,它采用一组输入并创建一个输出列表。如果我只需要使用前一个元素,则可以直接使用递归:

let buildElement head previous =
    // do something to create new float 
    1.0

let buildList inputs =
    let rec bootstrap elements previous = 

        let addElement head tail =
            let newElement = buildElement head previous
            newElement :: bootstrap tail newElement   

        match inputs with
            | []    -> []
            | h::t  -> addElement h t
    bootstrap inputs 1.0

但是,如果我想使用以前创建的元素(例如,我想将新值的平均值作为前一个值传递),我如何在内部函数中访问它们?我是否在外部函数中创建了一个集合并将其填充到内部函数中?如果是这样,我是否需要让它变得可变?

3 个答案:

答案 0 :(得分:2)

如果您需要根据过去值中的某些信息计算新值,那么您基本上会做与您现在正在做的事情相同的事情 - 而不是在previous中传递最后一个值,{ {1}}参数可以是您在过去时重新计算的过去值列表。

我认为在不知道具体例子的情况下很难给出更好的答案。但是,假设您想计算浮动平均值 - 为此,您需要计数和所有先前值的总和。您可以使用递归直接对其进行编码,也可以使用previous

Seq.scan

答案 1 :(得分:0)

如果是平均函数,你可以传递部分和和周围处理项目的数量,并用它来计算平均值。

对于一般解决方案,您可以将先前结果列表作为参数,使用::将下一个结果添加到其中,并在完成后反转整个事件。这有使你的函数尾递归的额外好处。

答案 2 :(得分:0)

  

如果我想使用之前创建的元素(例如,我想将新值的平均值作为前一个值传递),我如何在内部函数中访问它们?

这是foldscan(前缀折叠)。您将列表映射或折叠为新值,并累积影响结果的值。