在F#中,如何基于解析的有效负载对类型进行水合物化?

在F#中,如何基于解析的有效负载对类型进行水合物化?,f#,F#,我来自命令式编程背景,在理解如何实现(应该是什么)一个相对简单的编程任务时遇到问题 假设我有一个F型: 我希望基于分隔的负载创建并创建此类型的实例: DE=MyDescription;AC=0 其中AC为0表示false,1表示true 我编写了两个函数来执行解析: let RecordParser (record:string) = record.Split([|';'|], StringSplitOptions.RemoveEmptyEntries) let Attribute

我来自命令式编程背景,在理解如何实现(应该是什么)一个相对简单的编程任务时遇到问题

假设我有一个F型:

我希望基于分隔的负载创建并创建此类型的实例:

DE=MyDescription;AC=0
其中AC为0表示
false
,1表示
true

我编写了两个函数来执行解析:

let RecordParser (record:string) = 
    record.Split([|';'|], StringSplitOptions.RemoveEmptyEntries)

let AttributeParser (kvp:string) =
    kvp.Split [|'='|]
解析分隔的有效负载以返回MyType的新实例(该实例由解析的
Description
Active
值组成)的函数的实现是什么样的

我尝试了一种使用
Array.iter
的路由,但是当
match
ing键时,我似乎无法将其编译。我已经做到了:

let Hydrater payload
    let kvps = RecordParser payload
    kvps |> Array.iter(fun (x) -> 
    // How to match on the keys of "DE" and "AC" to extract the value and construct MyType
    ()
    )

让我们假设
MyType
被定义为:

您所描述的内容可以看作是要覆盖在默认值之上的值的累积:

let hydrate payload = 
    let kvps = RecordParser payload
    let startingValue = { Description = ""; Active = false }
    kvps 
    |> Seq.fold 
        (fun state kvp -> 
            match kvp with
            | [| 'Description'; '='; description |] -> { state with Description = description }
            | [| 'AC'; '='; '0' |] -> { state with Active = false }
            | [| 'AC'; '='; '1' |] -> { state with Active = true }
            | _ -> failwith "Not implemented") startingValue
这里的
startingValue
是“默认”值。获取
起始值
,并将其用作
状态
的初始值。每次对函数求值后,返回值将作为
状态
传递给函数的下一次调用。通常,可以使用
Seq.fold
替换C#中某些类型的
foreach
循环

这个F#:

大致相当于这个C#:


在本例中,您将执行与C#中相同的操作(因为它只在运行时才知道):检查您是否有足够的记录,检查每个记录是否有足够的部分,然后使用数组索引(
[i]
)和您常用的布尔和比较函数来提醒我速度有点慢,但你能解释一下Seq.fold是如何获得起始价值的吗?它是以某种方式隐式传递的吗?@thehowler我最新的编辑wrt Seq.fold有意义吗?是的。我错过了“state”值的隐式类型。
type MyType = {
    Description : string
    Active : bool
}
let hydrate payload = 
    let kvps = RecordParser payload
    let startingValue = { Description = ""; Active = false }
    kvps 
    |> Seq.fold 
        (fun state kvp -> 
            match kvp with
            | [| 'Description'; '='; description |] -> { state with Description = description }
            | [| 'AC'; '='; '0' |] -> { state with Active = false }
            | [| 'AC'; '='; '1' |] -> { state with Active = true }
            | _ -> failwith "Not implemented") startingValue
Seq.fold (fun state curr -> doSomething state curr) startingValue items
var state = startingValue;
foreach(var curr in items) 
{
    state = doSomething(state, curr);
}