隐式忽略此表达式的结果。考虑使用'ignore',例如'expr |>忽略',或'例如'let result = expr'

时间:2018-01-13 20:07:03

标签: f#

我正在尝试为出现hereF#代码构建Python等效代码,我的代码如下:

let tripleExponentialSmoothing series slen alpha beta gamma nPreds =
    let result : float list = []
    let mutable smooth = 0.
    let mutable trend = 0.
    let seasonals = initialSeasonalComponents series 12
    for i in 0..(series.Length+nPreds-1) do
    match i with
    | 0 ->     // initial values        
        smooth <- series |> Array.head |> float
        trend <- initialTrend series slen
        result |> List.append [series |> Array.head |> float] |> ignore
    | i when i >= series.Length -> // we are forecasting
        let m = i - series.Length + 1
        result |> List.append [(smooth + float m * trend) + seasonals.Item(i%slen)] |> ignore
    | _ -> 
        let v = series |> Array.head  |> float
        let lastSmooth = smooth
        smooth <- alpha*(v-seasonals.Item(i%slen)) + (1.-alpha)*(smooth+trend)
        trend <- beta * (smooth-lastSmooth) + (1.-beta)*trend
        seasonals.Item(i%slen) <- gamma*(v-smooth) + (1.-gamma)*seasonals.Item(i%slen)
        result |> List.append [smooth + trend + seasonals.Item(i%slen)] |> ignore
    result

我得到了以下错误:

  

警告FS0020:隐式忽略此表达式的结果。   考虑使用'ignore'明确地丢弃此值,例如“EXPR   |&GT;忽略',或'让'将结果绑定到名称,例如'让结果=   EXPR”。

我尝试将以上内容编写为以下Python代码的转换:

def triple_exponential_smoothing(series, slen, alpha, beta, gamma, n_preds):
    result = []
    seasonals = initial_seasonal_components(series, slen)
    for i in range(len(series)+n_preds):
        if i == 0: # initial values
            smooth = series[0]
            trend = initial_trend(series, slen)
            result.append(series[0])
            continue
        if i >= len(series): # we are forecasting
            m = i - len(series) + 1
            result.append((smooth + m*trend) + seasonals[i%slen])
        else:
            val = series[i]
            last_smooth, smooth = smooth, alpha*(val-seasonals[i%slen]) + (1-alpha)*(smooth+trend)
            trend = beta * (smooth-last_smooth) + (1-beta)*trend
            seasonals[i%slen] = gamma*(val-smooth) + (1-gamma)*seasonals[i%slen]
            result.append(smooth+trend+seasonals[i%slen])
    return result

我做了什么错误,以及与提到的Python相同的正确代码是什么。

2 个答案:

答案 0 :(得分:4)

您正在运行for作为副作用。

也许你想要一个seq表达式,我认为在Python中你有生成器,但在F#中记住一切都是表达式。

let tripleExponentialSmoothing series slen alpha beta gamma nPreds =
    let mutable smooth = 0.
    let mutable trend = 0.
    let seasonals = initialSeasonalComponents series 12 |> Dictionary 
    seq {
        for i in 0..(series.Length+nPreds-1) do
          match i with
          | 0 ->     // initial values        
              smooth <- series |> Array.head |> float
              trend <- initialTrend series slen
              yield series |> Array.head |> float
          | i when i >= series.Length -> // we are forecasting
              let m = i - series.Length + 1
              yield (smooth + float m * trend) + seasonals.[i%slen]
          | _ -> 
              let v = series |> Array.head  |> float
              let lastSmooth = smooth
              smooth <- alpha*(v-seasonals.[i%slen]) + (1.-alpha)*(smooth+trend)
              trend <- beta * (smooth-lastSmooth) + (1.-beta)*trend
              seasonals.[i%slen] <- gamma*(v-smooth) + (1.-gamma)*seasonals.[i%slen]
              yield smooth + trend + seasonals.[i%slen] }

因此,序列表达式的格式为seq { expr },并且在表达式中使用yield来生成结果。

答案 1 :(得分:2)

正如在另一个答案中所提到的,你试图改变for循环中的结果列表,但这是不可能的,因为默认情况下F#列表是不可变的。

如果您想直接遵循Python代码的样式,可以使用mutable ResizeArray

let tripleExponentialSmoothing series slen alpha beta gamma nPreds =
    let result = ResizeArray<_>()
    let mutable smooth = 0.
    let mutable trend = 0.
    let seasonals = initialSeasonalComponents series 12
    for i in 0..(series.Length+nPreds-1) do
      match i with
      | 0 ->     // initial values        
          smooth <- series |> Array.head |> float
          trend <- initialTrend series slen
          result.Add(series |> Array.head |> float)
      | i when i >= series.Length -> // we are forecasting
          let m = i - series.Length + 1
          result.Add((smooth + float m * trend) + seasonals.Item(i%slen))
      | _ -> 
          let v = series |> Array.head  |> float
          let lastSmooth = smooth
          smooth <- alpha*(v-seasonals.Item(i%slen)) + (1.-alpha)*(smooth+trend)
          trend <- beta * (smooth-lastSmooth) + (1.-beta)*trend
          seasonals.Item(i%slen) <- gamma*(v-smooth) + (1.-gamma)*seasonals.Item(i%slen)
          result.Add(smooth + trend + seasonals.Item(i%slen))

这不是非常惯用的F#代码,但它解决了您的直接问题。对于更实用的解决方案,您可以使用Gustavo提到的序列表达式并逐个生成结果,但您仍然将smoothtrend保留为可变变量,因此可能有更好的方法这样做 - 但如果不了解更多关于算法的信息,那很难猜到。