4

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 を使用せずにこれらすべてを行うためのより良い方法があるに違いないと考えていました。

パターン マッチングと再帰を使用して、これらのネストされた構造をより適切に解析するにはどうすればよいでしょうか?

4

2 に答える 2

6

いくつかのポインタ:

  1. タプルのリストを返す代わりに、タプルのシーケンスを返します -seq { }シーケンスを作成するための計算式を使用します。
  2. if/else 部分を型の関数として抽出し、この関数を式のMessage -> (BBResponseType * string)中で使用しますseq
  3. この新しい関数 (メッセージをタプルに変換する) 内で、パターン マッチングを使用して、返される (BBResponseType * string) の種類を特定します。
于 2013-08-02T06:30:26.673 に答える