f# - 平均 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)
根本没有帮助。
解决方案
您()
对看似记录的内容使用分隔符,但记录使用{}
分隔符。将您的第一个管道更改为:
(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 = 5
值x
不能更改,并且在该代码块的其余部分中始终等于 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
,因为我假设您的Ask
andBid
值是浮点数。如果它们是整数,请删除该float
转换,但请注意 F# 在对整数进行除法时使用整数5 / 2
除法,例如 的值将是 2,而不是 2.5。如果你想要 2.5,你将不得不划分浮点数,5.0 / 2.0
.
推荐阅读
- python - 写很多列(超过20)
- c++ - 返回 x; 在 C++ 中没有返回整数值
- c - 安装 Gstreamer 插件,缺少 avi demuxer
- printing - 有没有办法在每次打印后自动送入标签,然后在 Zebra 打印机的下一次打印之前自动回送送入的标签?
- google-cloud-platform - GCP Cloundrun 覆盖响应标头字符
- reactjs - 刷新页面时出现 React.Children.only 错误
- turtle-graphics - 在 Python Turtle 中设计暂停和取消暂停功能
- python - 如何在 SQLAlchemy 中同时使用 JOIN 和 SELECT AS?
- java - 从 Firestore 中提取数据 document.getData()
- gitlab - 如何在 Gitlab CI 中编写规则以在合并到 master 后运行作业?