F#联合案例参数化

Ste*_*RKP 3 f# discriminated-union

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

我遇到的问题是,我对函数范式/ F#相对较新,并且我不确定是否有一种方法可以处理模式匹配/判别以外的联合案例。这个例子可能会问一个问题,如果它们遵循相同的逻辑,为什么它们是不同的情况,答案是我真的试图在一个联合中为域描述目的使用不同的情况。我仍然在尝试创建一些通用模块时寻求平衡,但是将类型安全性用于领域特殊性。在此示例中,我将从通用输入模块绑定此Domain用法的所有可能字段。

本质上,是否有某种方式可以使用“特殊情况”作为参数?如何将其传递/管道输送?

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)
Run Code Online (Sandbox Code Playgroud)

这不是关键性的,因为它起作用了,我也相信在这些领域特定功能的字段的附加描述中有一些价值。但是,我只是想看看是否有比我目前正在做的更好的做法。目的是潜在地允许我构建一些更通用的功能,然后我可以将域描述更专有地保留在DU类型定义中,但可以与通用功能一起使用。

任何想法或意见都值得赞赏...

更新:修正了一些错别字,并澄清了我的目标。还添加了在初始示例中使用的DU定义。

type UserRegistrationInputValue =
    | ID of InputStringValue
    | Name of InputStringValue
    | Email of InputStringValue
    | Phone of InputStringValue
Run Code Online (Sandbox Code Playgroud)

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

DU的定义说明了我要实现的领域特定性,同时依赖于我的通用模块进行处理/行为。该示例中的命名/定义函数保留在我的域中,因为它们使用特定于域的类型。但是,我发现,在我目前的课程中,对于不同的域定义,重复了很多此代码...

The*_*Fox 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
Run Code Online (Sandbox Code Playgroud)

您可以将垂直管道|作为“ OR”模式匹配项放在模式匹配项中:

let validateUserRegistrationInputField requirementsSelector fieldValue =
    match fieldValue with
    | ID fv | Name fv | Email fv | Phone fv ->
        validateInputValue fv (requirementsSelector fv)
Run Code Online (Sandbox Code Playgroud)

如果执行此操作,那么所有被“或”运算的模式都需要绑定具有相同名称和类型的值。在这种情况下,fv所有DU案例的类型必须相同。