代码之家  ›  专栏  ›  技术社区  ›  Thomas

求f中c对象的平均值,我的语法有什么问题

f#
  •  1
  • Thomas  · 技术社区  · 5 年前

    Candle (这是股票市场数据)我需要将其中的一些对象平均化为一个对象。

    对象非常简单,它们只包含一个字段float fields( Bid , Ask , Bidvolume , Askvolume )

    我写了这段代码,但我不明白为什么它不能编译:

                let zero = new Candle()
                let avg =   entries
                            |> List.fold (fun acc elem ->
                                    (
                                        Ask = acc.Ask + elem.Ask,
                                        Bid = acc.Bid + elem.Bid,
                                        AskVolume = acc.AskVolume + elem.AskVolume,
                                        BidVolume = acc.BidVolume + elem.BidVolume
                                    )
                                ) zero
                            |>
                                (
                                    TimeStamp = time,
                                    Ask = Ask / entries.Count,
                                    Bid = Bid / entries.Count,
                                    AskVolume = AskVolume / entries.Count,
                                    BidVolume = BidVolume / entries.count,
                                    Integrity = entries.Count / expectedCount
                                )
    

      BooksCandle.fs(154, 41): [FS0039] The value or constructor 'Ask' is not defined.
      BooksCandle.fs(154, 51): [FS0039] The field, constructor or member 'Ask' is not defined.
      BooksCandle.fs(155, 41): [FS0039] The value or constructor 'Bid' is not defined. Maybe you want one of the following:   id
      BooksCandle.fs(155, 51): [FS0039] The field, constructor or member 'Bid' is not defined.
      BooksCandle.fs(156, 41): [FS0039] The value or constructor 'AskVolume' is not defined.
      BooksCandle.fs(156, 57): [FS0039] The field, constructor or member 'AskVolume' is not defined.
      BooksCandle.fs(157, 41): [FS0039] The value or constructor 'BidVolume' is not defined.
      BooksCandle.fs(157, 57): [FS0039] The field, constructor or member 'BidVolume' is not defined.
      BooksCandle.fs(159, 35): [FS0001] This expression was expected to have type    'bool * bool * bool * bool'    but here has type    'Candle'
      BooksCandle.fs(162, 37): [FS0001] This expression was expected to have type    'bool * bool * bool * bool -> 'a'    but here has type    ''b * 'c * 'd * 'e * 'f * 'g'
      BooksCandle.fs(170, 22): [FS0039] The value or constructor 'A' is not defined.
    

    所以,我猜我操作的对象不被视为 蜡烛 fun (acc : Candle) (elem : Candle) 一点用都没有。

    2 回复  |  直到 5 年前
        1
  •  2
  •   Nghia Bui    5 年前

    在F#,对象和记录是不同的东西。您可以创建如下记录值:

    { Foo = "apple"; Bar = "banana" }
    

    但是不能使用类似的语法来创建对象。以下代码无法编译:

    ( Foo = "apple", Bar = "banana" )
    

    因为它将被理解为:

    • 由两个组件组成的元组,因为它是 ( component1, component2 ) .
    • = .
    • Foo Bar .

    相反,你必须写: new MyClass ( Foo = "apple", Bar = "banana" )

    我想重写你的代码如下:

    let zero = new Candle ()
    let sum =
        entries
        |> List.fold
            (fun acc elem ->
                new Candle (
                    Ask = acc.Ask + elem.Ask,
                    Bid = acc.Bid + elem.Bid,
                    AskVolume = acc.AskVolume + elem.AskVolume,
                    BidVolume = acc.BidVolume + elem.BidVolume
                )
            )
            zero
    let avg = new Candle (
        TimeStamp = time,
        Ask = sum.Ask / float entries.Length,
        Bid = sum.Bid / float entries.Length,
        AskVolume = sum.AskVolume / float entries.Length,
        BidVolume = sum.BidVolume / float entries.Length,
        Integrity = float entries.Length / float expectedCount
    )
    

    请注意,F#type系统非常有限,因此我们必须显式地将整数转换为浮点。

        2
  •  3
  •   rmunn    5 年前

    () 似乎是记录但记录使用的分隔符 {} 分隔符。将第一个管道更改为:

    (fun acc elem ->
                {
                    Ask = acc.Ask + elem.Ask,
                    Bid = acc.Bid + elem.Bid,
                    AskVolume = acc.AskVolume + elem.AskVolume,
                    BidVolume = acc.BidVolume + elem.BidVolume
                }
    )
    

    然后,也改变第二管建议在切斯特外壳的答案。

    编辑: let zero = new Candle() 这句台词让我重新思考。你刚才说过 Candle 是C对象。那么在这种情况下,您实际要做的是对新创建的字段进行变异 zero <- 接线员。F级# 故意的 = <- 接线员。这个 操作员指 平等 let x = 5 x 无法更改 未标记 mutable 是一个对象,对象可能会改变其内部结构,但名称 <- 另一方面,运算符用于赋值。它看起来 不同的 = 因为你不能保证那个值永远存在。

    (fun acc elem ->
        acc.Ask <- acc.Ask + elem.Ask,
        acc.Bid <- acc.Bid + elem.Bid,
        acc.AskVolume <- acc.AskVolume + elem.AskVolume,
        acc.BidVolume <- acc.BidVolume + elem.BidVolume
        acc
    )
    

    acc 把它自己写在最后一行。函数的最后一个表达式是它的返回值;不 return

    |> (fun result ->
            result.TimeStamp <- time,
            result.Ask <- result.Ask / float entries.Count,
            result.Bid <- result.Bid / float entries.Count,
            result.AskVolume <- result.AskVolume / float entries.Count,
            result.BidVolume <- result.BidVolume / float entries.count,
            result.Integrity <- entries.Count / expectedCount
    )
    

    注意我是怎么转化的 entries.Count float Ask Bid 值是浮点数。如果它们是整数,去掉它 浮动 除法当你除数时,例如 5 / 2 5.0 / 2.0 .

        3
  •  2
  •   Fyodor Soikin    5 年前

    我想试试看,但我猜你折叠后管子里的154号线?如果是这样,问题就出在语法上:而不是

    |> (.... 
    

    你需要用管道把折叠的结果 进入之内

    |> fun reduced -> { TimeStamp = time
                        Ask = reduced.Ask/entries.Count
                        .... }