1

我正在尝试在 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

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

4

3 回答 3

2

如果您需要根据过去值中的一些信息计算新值,您基本上会做与现在正在做的事情相同的事情 - 而不是传递 ingle last 值previousprevious参数可以是过去值的列表你在你去的时候重新计算。

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

[ 1.0 .. 100.0 ] 
|> Seq.scan (fun (count, sum) elem -> count + 1, sum + elem) (0, 0.0)
|> Seq.map (fun (count, sum) -> sum / float count)
于 2012-05-31T12:49:26.723 回答
0

在平均函数的情况下,您可以传递部分总和和处理项目的数量并使用它来计算平均值。

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

于 2012-05-31T10:44:31.103 回答
0

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

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

于 2012-05-31T20:13:13.917 回答