Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 在F中正确使用活动模式#_F#_Active Pattern - Fatal编程技术网

F# 在F中正确使用活动模式#

F# 在F中正确使用活动模式#,f#,active-pattern,F#,Active Pattern,我正在使用活动模式解析csv格式的使用日志中的使用事件。下面列出了激活的图案零件。在中解析整个文件效果很好,生成的序列中充满了各种各样的usageevent type SystemName = string type SystemVersion = string type MAC = string type Category = string type Game = string type Setting = string type StartupLocation = string type

我正在使用活动模式解析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

此匹配不起作用,因为循环函数需要
字符串列表
。还有什么其他方法可以使用联合中包含的数据,或者我应该匹配输入,然后将其存储在常规类型中?

此代码有两个问题:

  • 区分联合
    UsageEvent
    和活动模式选择函数具有相同的名称

  • 递归循环函数在编写时不是递归的,它不调用自身

  • 当您在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  
    

    要添加到@Petr的答案中-
    UsageEvent
    案例和您的活动模式案例具有相同的名称,因此稍后定义的活动模式会隐藏联合类型。这很可能就是
    字符串列表的来源

    我只需完全删除活动模式,然后向
    UsageEvent
    添加一个
    Parse
    函数(或者更确切地说是一个
    ParseParts
    ,因为您希望为它提供一个字符串列表)

    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...) 
    
    活动模式很可爱,但你真的需要一个好的场景让它们发光。否则,如果您可以不使用普通函数,只需使用普通函数即可