F# 联合案例参数化

3

我正在查看我的代码,不确定是否有一种方法可以概括这些代码块:

我的问题是,我对函数式编程范式/F #相对较新,不确定在模式匹配/区分之外是否有一种处理联合案例的方法。这个例子可能会问为什么如果它们遵循相同的逻辑,它们是不同的情况,答案是我真的想在联合中使用不同的情况来进行域描述; 我仍在努力寻找平衡点,旨在创建一些通用的模块,但利用类型安全来满足特定领域的需求。在这个例子中,我绑定了来自通用输入模块用于此域使用的所有可能字段。

基本上,是否有一种使用特定情况作为参数的方法?如何传递/管道它?

let updateUserRegistrationInputFieldValue changeValue fieldValue =
    match changeValue with
    | ID cv -> match fieldValue with | ID _ -> ID cv | _ -> fieldValue
    | Name cv -> match fieldValue with | Name _ -> Name cv | _ -> fieldValue
    | Email cv -> match fieldValue with | Email _ -> Email cv | _ -> fieldValue
    | Phone cv -> match fieldValue with | Phone _ -> Phone cv | _ -> fieldValue

let validateUserRegistrationInputField requirementsSelector fieldValue =
    match fieldValue with
    | ID fv -> validateInputValue fv (requirementsSelector fv)
    | Name fv -> validateInputValue fv (requirementsSelector fv)
    | Email fv -> validateInputValue fv (requirementsSelector fv)
    | Phone fv -> validateInputValue fv (requirementsSelector fv)

这不是很重要,因为它可以工作,而且我认为在这些特定领域的函数中增加字段的描述也有一定的价值。但是,我更想知道是否有比我当前做法更好的方法。目标是可能允许我构建一些更通用的函数,然后将领域描述更专门地保留在DU类型定义中,但与一般函数一起使用。

任何想法或输入都会受到赞赏...

更新:修正了一些拼写错误,澄清了我的目标。此外,还添加了在初始示例中使用的DU定义。

type UserRegistrationInputValue =
    | ID of InputStringValue
    | Name of InputStringValue
    | Email of InputStringValue
    | Phone of InputStringValue

这个类型同时用于第一个函数中的'changeValue'和'fieldValue'参数,而在第二个函数中则是'fieldValue'。 (requirementsSelector是一个以该DU类型作为参数的函数)

DU类型的定义说明了我想要达到的领域特定性水平,同时依赖我的通用模块进行处理/行为。示例中的命名/定义函数被保留在我的领域中,因为它们使用了领域特定的类型;但是,我看到,在当前情况下,为不同的领域定义重复编写此代码...


3
你能否编辑问题,包括所示案例的区分联合类型定义? - TheQuickBrownFox
1个回答

5

在模式匹配之前,您可以将多个项目放入元组中,并同时匹配它们。这给您提供了一个“AND”模式匹配:

let updateUserRegistrationInputFieldValue changeValue fieldValue =
    match changeValue, fieldValue with
    | ID cv, ID _ -> ID cv  // matches when changeValue is ID **AND** fieldValue is ID
    | Name cv, Name _ -> Name cv
    | Email cv, Email _ -> Email cv
    | Phone cv, Email _ -> Phone cv
    | _ -> fieldValue

在模式匹配中,您可以使用竖线|表示“或”匹配:

let validateUserRegistrationInputField requirementsSelector fieldValue =
    match fieldValue with
    | ID fv | Name fv | Email fv | Phone fv ->
        validateInputValue fv (requirementsSelector fv)

如果这样做,那么所有使用“OR”连接的模式需要绑定具有相同名称和类型的值。在这种情况下,“fv”必须是所有DU案例的相同类型。

谢谢。这些是有用的建议,我已经将它们纳入了我的代码中。我感觉这段代码更加简洁,对于新读者来说更容易理解该函数的意图和用法(它是针对所有输入字段进行ListMapped操作,只有在Change匹配的情况下才会更新,否则保留原始值)。这样更清晰明了。谢谢。此外,第二个函数更新使其更易于维护,并使域特定性更加集中。谢谢! - SteelCityRKP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接