F# 在F中正确使用活动模式#
我正在使用活动模式解析csv格式的使用日志中的使用事件。下面列出了激活的图案零件。在中解析整个文件效果很好,生成的序列中充满了各种各样的usageeventF# 在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
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
和活动模式选择函数具有相同的名称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...)
活动模式很可爱,但你真的需要一个好的场景让它们发光。否则,如果您可以不使用普通函数,只需使用普通函数即可