首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >F#中活动模式的适当使用

F#中活动模式的适当使用
EN

Stack Overflow用户
提问于 2014-12-22 20:40:32
回答 2查看 383关注 0票数 3

我使用一个活动模式来解析csv格式化的使用日志中的使用事件。下面列出了活动模式部分。解析整个文件运行良好,生成的序列被各种UsageEvents填充。

代码语言:javascript
复制
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。我想遍历列表,根据某些逻辑从列表中创建一棵树,但是在解析之后,我无法匹配序列中的条目。

代码语言:javascript
复制
let CountSystemStart (entries : UsageEvent list) =
    let rec loop sum = function
        | SystemStart(_,_,_,_) -> sum + 1
        | _ -> sum
    loop 0 entries

这种匹配不起作用,因为循环函数需要一个string list。我还能以什么其他方式使用联合中包含的数据,或者应该匹配输入,然后将其存储在常规类型中呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-23 01:53:17

为了添加到@Petr的答案- UsageEvent案例和您的活动模式案例具有相同的名称,所以后面定义的活动模式隐藏了联合类型。这也是string list最有可能的来源。

我将直接删除活动模式,并向Parse添加一个ParseParts函数(或者更确切地说是一个ParseParts,因为您希望为它提供一个字符串列表)。

代码语言:javascript
复制
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...) 

活动模式是可爱的,但你真的需要一个好的场景,让他们发光。否则,如果可以使用普通函数,只需使用普通函数即可。

票数 7
EN

Stack Overflow用户

发布于 2014-12-22 21:07:11

此代码有两个问题:

  1. 识别联合UsageEvent和活动模式选择函数具有相同的名称
  2. 递归循环函数不是递归的,因为它是写的-它不调用自己。

当您在UsageEvent列表上匹配时,尝试使用完整类型名称。

我会将您的CountSystemStart函数重写为:

代码语言:javascript
复制
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  
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27610103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档