首页 > 解决方案 > 平均 f# 中的 c# 对象列表,我的语法有什么问题

问题描述

我有一个名为Candle(股票市场数据)的 C# 对象列表,我需要将其中一些对象平均为一个对象。

对象非常简单,它们只包含一个字段 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.

所以,所以我猜我正在操作的对象不被视为 a Candle,但 usingfun (acc : Candle) (elem : Candle)根本没有帮助。

标签: f#

解决方案


()对看似记录的内容使用分隔符,但记录使用{}分隔符。将您的第一个管道更改为:

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

然后还按照 Chester Husk 的回答中的建议更改第二个管道。

编辑:不,等等。你有一条线的事实let zero = new Candle()让我重新思考。你之前说过这Candle是一个 C# 对象。然后在这种情况下,您实际上要做的是改变新创建zero对象的字段。在这种情况下,您需要<-操作员。F#特意区分了=and<-运算符。=运算符表示相等,也用于因为的let x = 5x 不能更改,并且在该代码块的其余部分中始终等于 5,因为x没有标记mutable。(如果x是一个对象,该对象可能会改变其内部结构,但名称x将始终引用该对象)。<-另一方面,运算符用于赋值。它看起来与运算符不同=因为您不承诺该值将永远存在。

所以,话虽如此,你真正需要的是改变你的累加器函数看起来像这样:

(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通过在最后一行单独编写它来返回的。F# 函数中的最后一个表达式是它的返回值;不需要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为 a 的float,因为我假设您的AskandBid值是浮点数。如果它们是整数,请删除该float转换,但请注意 F# 在对整数进行除法时使用整数5 / 2除法,例如 的值将是 2,而不是 2.5。如果你想要 2.5,你将不得不划分浮点数,5.0 / 2.0.


推荐阅读