我在与有区别的联合使用“ with”时遇到一些问题:
type NaturalPerson = {
FirstName: string
LastName: string
}
type CorporateEntity = {
Name1: string
Name2: string option
}
type Person =
| Natural of NaturalPerson
| Company of CorporateEntity
let company = Company { Name1 = "Foo Bar AG"; Name2 = Some "Baz" }
现在,我想将Name2更改为None,但是我不知道怎么做。 像这样:
let company2 = Company { company with Name2 = None }
在我的“真实示例”中,这是嵌套的,否则我可以使用正确的类型。
也许这是不可能的,因为我必须对不存在的边缘情况进行模式匹配(但是编译器不够聪明才能知道)。
答案 0 :(得分:2)
这是您要执行的操作(我假设如果变量company
是NaturalPerson
,那么您希望它保持不变):
match company with
| Person _ -> company
| Company corpEntity -> Company { corpEntity with Name2 = None }
答案 1 :(得分:2)
如果您将其扩展一些,则更容易发现问题。实际上,命名的困难可能在于此。
let company = Company { Name1 = "Foo Bar AG"; Name2 = Some "Baz" } // Person
let company2 = Company { company with Name2 = None } // Person, but broken because expecting company to be type of CorporateEntity
因此,您尝试创建类型为CorporateEntity
的{{1}},这是不相同的。
这有效,因为使用了正确的类型。
Person
我添加了类型并更改了名称,以使类型更加明显。
您可以为此let c1 : CorporateEntity = { Name1 = "Foo Bar AG"; Name2 = Some "Baz" }
let p1 : Person = Company c1
let c2 : CorporateEntity = { c1 with Name2 = None }
let p2 : Person = Company c2
...
match
如果您想匹配某个函数,可以这样做:
match company with // <- rename company to person so it is clearer
| Natural _ -> company
| Company c -> Company { c with Name2 = None }
或更简洁地说:
let noCompanyName2 (c:CorporateEntity) = // c:CorporateEntity -> Person
let { Name1 = n1; Name2 = _ } = c
let company3 = Company { Name1 = n1; Name2 = None }
company3
希望这会有所帮助。