我在 F# 中使用第三方供应商的 API。初始化时,API 返回一个嵌套 msg 容器的 C# 对象。它填充了状态消息,并且可能包含错误消息。供应商提供了我已移植 F# 的 C# 示例解析例程。
代码示例循环通过嵌套的 msg 容器提取致命和非致命错误,然后返回类型的元组列表BBResponseType * string
响应枚举:
type BBResponseType =
| Status = 0
| Data = 1
| Error = 2
| FatalError = -1
我的 F# 端口如下所示:
member private this.ProcessStatusMsg(eventObj: Blpapi.Event) =
let responseLst = List<(BBResponseType * string)>()
for msg in eventObj do
if msg.MessageType.Equals(SUBSTARTED) then
if msg.GetElement(EXCEPTIONS).NumValues > 0 then // <- check for errors/exceptions
let e = msg.GetElement(EXCEPTIONS)
for i in 0..e.NumValues-1 do
let error = e.GetValueAsElement(i)
let field = error.GetElementAsString(FieldID)
let reason = error.GetElement(REASON)
let message = sprintf "Subscription Started w/errors( Field: %s \n Reason: %s)" field (reason.GetElementAsString(DESCRIPTION))
responseLst.Add(BBResponseType.Error, message)
else
let message = sprintf "Subscription Started"
responseLst.Add(BBResponseType.Status, message)
if msg.MessageType.Equals(SUBSCFAILURE) then // <- check for subscriptions failure
if msg.HasElement(REASON) then
let reason = msg.GetElement(REASON)
let desc = reason.GetElementAsString(DESCRIPTION)
let message = sprintf "Real-time Subscription Failure: %s" desc
responseLst.Add(BBResponseType.FatalError, message)
else
let message = sprintf "Subscription Failure: (reason unknown) "
responseLst.Add(BBResponseType.FatalError, message)
responseLst
完成后,我看着它并想,“哇,这几乎是你所能得到的没有功能的东西,而且仍然在 F# 中编码。”
它看起来确实比 C# 版本更清晰和简洁,但我认为必须有更好的方法来完成这一切,而无需使用这么多循环和 if/then's。
如何使用模式匹配和递归更好地解析这些嵌套结构?