3

csv 形式の使用状況ログで使用状況イベントを解析するために、アクティブ パターンを使用しています。アクティブなパターン パーツは次のとおりです。ファイル全体の解析はうまく機能し、生成されるシーケンスにはあらゆる種類の UsageEvent が含まれます。

type SystemName = string
type SystemVersion = string
type MAC = string
type Category = string
type Game = string
type Setting = string
type StartupLocation = string

type UsageEvent =
    | SystemStart of DateTime * SystemVersion * SystemName * MAC
    | SystemEnd of DateTime
    | GameStart of DateTime * Category * Game * Setting * StartupLocation
    | GameEnd of DateTime * Category * Game
    | Other

let (|SystemStart|SystemEnd|GameStart|GameEnd|Other|) (input : string list) =
    match List.nth input 0 with
    | "SystemStartedEvent" ->
         SystemStart (DateTime.Parse (List.nth input 1), List.nth input 2, List.nth input 3, List.nth input 4)
    | "SystemEndedEvent" ->
         SystemEnd (DateTime.Parse (List.nth input 1))
    | "GameStartedEvent" ->
         GameStart (DateTime.Parse (List.nth input 1), List.nth input 2, List.nth input 3, List.nth input 4, List.nth input 5)
    | "GameEndedEvent" ->
         GameEnd (DateTime.Parse (List.nth input 1), List.nth input 2, List.nth input 3)
    | _ ->
         Other

私が抱えている問題は、おそらく ActivePattern を間違った方法で使用していることです。リストをたどって、いくつかのロジックに基づいてツリーを作成したいのですが、解析後にシーケンス内のエントリを一致させる方法がありません。

let CountSystemStart (entries : UsageEvent list) =
    let rec loop sum = function
        | SystemStart(_,_,_,_) -> sum + 1
        | _ -> sum
    loop 0 entries

ループ関数にはstring list. ユニオンに含まれるデータを他にどのように使用できますか、または入力を照合してから通常の型に保存する必要がありますか?

4

2 に答える 2

6

@Petrの答えに追加するにUsageEventは、ケースとアクティブなパターンのケースは同じ名前であるため、後で定義されるアクティブなパターンはユニオンタイプを隠します。string listおそらく、それが物事の由来です。

アクティブなパターンを完全に削除し、Parse関数 (ParseParts文字列のリストをフィードしたいので ) を. に追加しますUsageEvent

type UsageEvent =
    | SystemStart of DateTime * SystemVersion * SystemName * MAC
    | (...and so on...)
    static member ParseParts (input: string list) =
        match input with
        | ["SystemStartedEvent"; date; version; name; mac] ->
            SystemStart (DateTime.Parse date, version, name, mac)
        | (...and so on...) 

アクティブなパターンはかわいいですが、それらを輝かせるには適切なシナリオが必要です。それ以外の場合は、単純な関数を使用して回避できる場合は、単純な関数を使用してください。

于 2014-12-23T01:53:17.160 に答える
2

このコードには 2 つの問題があります。

  1. 判別共用体UsageEventと能動パターン選択関数は同じ名前です

  2. 再帰ループ関数は、書かれているように再帰的ではありません-それ自体を呼び出しません。

UsageEvent リストで照合する場合は、完全なタイプ名を使用してみてください。

CountSystemStart 関数を次のように書き直します。

let CountSystemStart (entries : UsageEvent list) =
    let rec loop sum = function
        | [] -> sum 
        | (UsageEvent.SystemStart(_))::rest -> loop (sum + 1) rest
        | _::rest -> loop sum rest
    loop 0 entries  
于 2014-12-22T21:07:11.790 に答える